114e010ae6e53ab109f94340fd89a337f44c8c4a
[freeside.git] / TODO
1 $Id: TODO,v 1.29 1999-04-14 11:27:06 ivan Exp $
2
3 If you are interested in helping with any of these, please join the mailing
4 list (send a blank message to ivan-freeside-subscribe@sisd.com) to avoid 
5 duplication of effort.
6
7 ---
8
9 hmm... maybe svc_acct__shell should check off the legal shells list if
10 applicable?  yeah... cool.
11
12 payinfo field should me much larger than 16
13
14 default (and ordering) state/county/country config file
15
16 [Mon Apr 12 20:31:21 1999] [error] [Mon Apr 12 20:31:21 1999] null: Error closing true: Broken pipe at /usr/local/lib/site_perl/FS/cust_main.pm line 615.
17
18 javascript (yuck!) "are you sure?" confirmation on cancelations, etc.
19 (view/cust_pkg and view/svc_*)
20
21 get rid of time2str("%D") which formats dates in a non-y2k-safe looking fashion
22 (all the actual date handling uses UNIX timestamps and is fine)
23
24 uncomment expire in view/cust_pkg.cgi and find the expire cron from fsold
25
26 (Test this)
27 one-time/per-customer/? changes in rates and descriptions ('remembered
28 invoices'): implement by creating a new package on the fly... but it isn't 
29 associated with any agent types so it won't show up for other customers to buy.
30 (but also... make sure they go away when the customer does! - need this? :
31  one-off package edits! : need a cust_pkgs or cust_part_pkgs or something table,
32  with custnum and partpkg (like type_pkgs)
33 (what happens if you hit "custom pricing" but the pricing is already custom?)
34
35 Lay out any remaining ugly forms better.
36
37 remove "records identical" warning?  gets in the way of more important stuff.
38 or fix logic which tries to update identical records??
39 1.2 should be quiet enough that the error log is useful, hopefully.
40
41 Postgres has a maximum column length of 31 characters (but see NAMEDATALEN in
42 postgres_ext.h).  part_svc has columns like: svc_acct__radius_Attribute_flag
43 (22 characters!)  It seems that stuff over the limit is silently ignored,
44 so we get 4 characters back.  So, Radius_Attributes are max 13 characters with
45 stock Postgres.  see rfc2138 for what's affected
46 What's a good fix?  (besides recompiling postgres with NAMEDATALEN 64)
47 (mysql has a 64 character max column length.  others?)
48
49 [Mon Mar 29 06:57:56 1999] -e: Use of uninitialized value at /usr/lib/perl5/Date/Format.pm line 333.
50 (when sending mail in cust_main.pm::bill or svc_domain.pm)
51
52 look at DBIx::Recordset!  (and Tie::DBI, and...)
53
54 undefined conf/lpr gives this uninfomative error:
55 [Fri Feb 26 16:42:36 1999] bill.cgi: Can't do bidirectional pipe at
56 /usr/lib/per
57 l5/site_perl/FS/cust_main.pm line 629.
58 [Fri Feb 26 16:42:38 1999] bill.cgi: Error closing : Broken pipe at
59 /usr/lib/per
60 l5/site_perl/FS/cust_main.pm line 631.
61 So give a meaningful error!
62
63 password and slipip stuff in svc_acct.pm store need to be split into two fields or something, so the silliness in svc_acct.pm and svc_acct.export with looking at the data to decide what to do with it can be fixed
64
65 i10n: Apache::Language
66
67 Apache::Session?  Other useful Apache::* ?
68
69 email invoices are only sent for the BILL payby.  If setup, should statements
70 (since they're not invoices) be sent for COMP and CARD as well?
71
72 $cgi->keywords is causing the (hard to trace) error:
73         Use of uninitialized value at (eval 5) line 5
74
75 edit/cust_main.cgi gives an uninformative error message:
76 > Can't call method "agentnum" without a package or object reference at   
77 > /usr/local/apache-ssl/htdocs/freeside/edit/cust_main.cgi line 116.
78 if there are no agents.
79
80 (is this missing on any web screens?  (easy with $cust_svc->label)
81 Add the ability for services to filter information up to the package level
82 for web screens, so you can select a particlar package based
83 on username or domain name, etc.
84
85 Allow a cancelled/suspended/active status from packages to bubble up to
86 the customer lists.  Put active, then suspended, then cancelled accounts.
87 Similar ordering on the package listing inside a single customer.
88
89 false laziness: edit/cust_main.cgi got some parts copied from edit/svc_acct.cgi
90 the web interface in general needs to be redone in a more abstract way.
91
92 false laziness: some of search/svc_acct_sm.cgi was copied to search/svc_domain.cgi.  but web interface in general needs to be rewritten in a mucho cleaner way.
93
94 Portability: in FS::Record, $sth->execute does not return a number of rows for all DBD's.  see man DBI
95
96 subroutine the where clause (eventually all SQL) as OO perhaps (has anyone done this?)
97
98 add a select method to FS::Record?
99
100 one-time/per-customer/? changes in rates and descriptions ('remembered
101 invoices'): implement by creating a new package on the fly... but it isn't 
102 associated with any agent types so it won't show up for other customers to buy.
103 (but also... make sure they go away when the customer does! - need this? :
104  one-off package edits! : need a cust_pkgs or cust_part_pkgs or something table,
105  with custnum and partpkg (like type_pkgs)
106 (what happens if you hit "custom pricing" but the pricing is already custom?)
107
108 You can't delete the stuff under administration yet.  Add this,
109 _including_ making sure the thing you are deleting is not in use!
110
111 add links on view/cust_main.cgi to setup services, like view/cust_pkg.cgi
112
113 FS::cust_pkg _require_'s FS::$svc, but this won't work with %FS::UID::callback
114 loading of configuration.  (pry need same idea, but will run immediately if
115 context allows).  Looks like error is masked by 'use FS::cust_svc' which in
116 turn 'use's FS::{svc_acct, svc_acct_sm, svc_domain}' which is now explicit
117 w/comments in source
118
119 Allow a cancelled/suspended/active status from packages to bubble up to
120 the customer lists.  Put active, then suspended, then cancelled accounts.
121 Similar ordering on the package listing inside a single customer.
122
123 svc_domain.pm mail sending uses Date::Format which doesn't seem to pick up 
124 correct timezone.
125
126 view/svc_domain.cgi needs to know the domain might be unaudited (cosmetic)
127
128 remove whois_hack set to 1 for svc_domain.pm?  add all known registries and
129 whois accordingly.
130 .us domains and others!
131 site_perl/svc_domain.cgi (hmm... or maybe should have a button?  or maybe svc_domain.pm should handle this) should set $whois_hack for non-internic domains, so you can add them...
132
133 turn on the depriciation warnings for [e]idiot in FS::CGI. Stop using [e]idiot
134 the last places it is (htdocs/search/ htdocs/misc/ htdocs/misc/process)
135
136 (test cust_main.pm with cybercash v2 and v3, especially with the callback
137  stuff AND with mod_perl w/cybercash v2 kludge in package main)
138 (callback stuff should be eliminated by now)
139
140 bah, table/itable/*table in FS::CGI is silly.
141
142 doc Apache::AuthDBI as well
143 ..
144 Provide sample httpd.conf files.
145
146 hey look: Tie::DBI!  Check that out.  Override its commit with something that
147 does perl-side caching for ? a performance improvement and as an emulation
148 layer to plug in f.ex mysql's atomic transactions
149 ..
150 Record.pm uses does some non-portable DBI things.  MySQL and Pg seem fine.
151 Fix it anyway unless we migrate to Tie::DBI.
152
153 faq
154
155 cust_bill.pm uses '==' comparison on dates because they're currently ints
156
157 config file for allowed card types
158
159 write instructions for adding new services w/svc_Common.pm.  Get rid of all
160 places where svc_* tables are hardcoded (rename svc_acct_pop to part_pop so
161 we can do that)
162
163 test and document libapache-dbi-logger (woo!)
164
165 radius logfile parsing and perl expression check.
166
167 Fix in cust_bill BUGS: 
168 There is an off-by-one error in print_text which causes a visual error (Page 1
169 of 2 printed on some single-page invoices).
170
171 fields should be a method against a FS::Record or derived object, as well as
172 being something you can call as FS::Record::fields('tablename').  Might
173 even be able to handle both in the same routine (that would be neato).
174
175 Immediate removal of incorrectly entered check payments (can't take too
176 long to do this, or accounting is fubared).
177
178 Add code to move from one service to another (POP to SLIP/PPP, etc.).
179 This _should_ be possible by working off the rules in part_svc rather than
180 hardcoding anything in.  The rules in part_svc may need some elaboration,
181 perhaps.
182
183 Use ut_ FS::Record methods in all derived classes (possibly some from dbdef?... eventually all from dbdef??? - but then `dbdef-create' would be impossible as there would be metadata we couldn't ask the backend for.  hmm.)
184
185 (bring back from fsold, ) Generalize config-sending stuff and make more configurable.
186 Expand the HylaFAX interface (also possibly generalize for other fax
187 softwar ie .comfaxe); allow things like arbitrary faxes of sales
188 literature, specific troubleshooting documents and so on.  Maybe even
189 allow users to do this (though that might not belong in Freeside).
190 misc/sendconfig.cgi
191 misc/process/sendconfig.cgi
192 Configure fax recipients via a separate box rather than using the finger
193 name or first+last from cust_main.
194
195 move all phone number logic out of Freeside - let HylaFAX or whatever
196 handle it.
197
198 soundex searches for customer name and company?  where are free soundex tools? (standard Text::Soundex duh) - I could have sworn I saw Text::Soundex on CPAN?!
199
200 should be able to link on some field in email alias (right now you can link
201 on username or domain with a fallback to svcnum)
202
203 generalize and make configurable new invoice printing scheme in FS::cust_main::collect (past due)
204
205 deleting an svc_domain should delete all associated svc_acct_sm records.
206 same with a svc_acct.
207
208 periodic password encrypter
209
210 Automated, configurable notification, suspension and cancellation of
211 defunct accounts.
212 ...
213 expire cron job
214 ...
215 Allow for a future setup date on accounts.
216
217 sub AUTOLOAD in FS::Record should warn? die? if used with a non-existant column
218 name?
219
220 edit (not just import, export and allow default/fixed) arbitrary radius stuff
221 in svc_acct
222 edit/svc_acct.cgi and edit/process/svc_acct.cgi should deal with arbitrary radius stuff
223
224 radius import should take DEFAULT entry and put it in /var/spool/freeside/conf/radius-default ; svc_acct.export should use it (and doc)
225
226 in UI, s/State/State\/Provence/go and s/County/County\/Locality/go
227
228 what else (besides l10n) for i18n? (money!)
229
230 audit htdocs/* for things that should be libraried and things that should be
231 new methods on the objects (need to do this before implementing a new UI)
232 all the big things are done
233
234 some places we die() where we should &FS::CGI::idiot (and perhaps vice-versa).
235 Decide based on whether or not the "error" should show up in logs.
236
237 all .cgi's should use standard header/footer and idiot() subroutines.  maybe HTML:: perl modules
238 for HTML creation.  Maybe Embperl or something along those lines.  ?
239
240 When running bin/bill, Fix this (Annoying but harmless):
241 Use of uninitialized value at /usr/local/lib/site_perl/FS/cust_pkg.pm line 99, <ADDRESS> chunk 4.
242 Use of uninitialized value at /usr/local/lib/site_perl/FS/cust_pkg.pm line 102, <ADDRESS> chunk 4.
243 Use of uninitialized value at /usr/local/lib/site_perl/FS/cust_pkg.pm line 105, <ADDRESS> chunk 4.
244
245 all cgi (but internal to the isp) places where package names are listed should also have
246 comment (like agent_type)
247
248 clean up $recref and other silliness and use -> calls where possible, or
249 one other alternative.  clean up everything else.
250 should FS::Record use Tie::Hash?  That would be very clean, but where do we
251 store the other information?  Maybe you could ask any FS::Record object for a
252 tied hash?
253
254 change all file access from regular open(FILE,) stuff to OO, because of 
255 problems scoping and passing filehandles like that.
256
257 the web interface should create a new object and use it instead of a blank
258 form for new records.  the create method of svc_ objects should set defaults
259 (from part_svc).
260
261 sub check in man FS::table_name should be rewriteen.  Get rid of $recref
262 stuff.  Make sure all fields that refer to other database are checked.
263
264 Integration with signup disks (are there any free ones?  Netscape?).
265
266 One-button cancel (+refund) for lusers who can't get online.
267
268 Keep information on virtual web servers (hostname, IP, host machine,
269 directory, etc.) and export this information for importation into the ISPs
270 web farm. 
271
272 Remove requirement that the first mail alias be the catchall?  Still make
273 sure only one catchall per domain is defined in any case, of course. 
274
275 Ability to move cust_pkg records from one customer to another? (proably
276 will need to cancel the old and create a new like when we move services
277 between packages). 
278
279 Auto-increment expired cards one year, and try again?
280
281 More non-US stuff - zip codes, country codes, foreign currencies, etc.
282
283 cust_refund.{cgi.pm} need to do cards xaxtions.  (now we only have cust_credit)
284
285 Nicer set of integrated reporting possibilities, like weekly sales totals
286 by customer, package, agent, referral, etc., aging reports sorted by lots
287 of different things, and so on.
288
289 Client/server setup for users to modify their own passwords, shells, etc,
290 via passwd or secure web interface (prelminary passwd/chfn/chsh
291 replacement done).  Complicated by the fact that we don't want to allow
292 incoming connections to the machine running Freeside, so we probably need
293 to have a daemon on each external shell or web machine that is contacted
294 by the Freeside machine.  Be very very careful for both traditional
295 security issues and DoS problems. 
296
297 An extension of the above to allow users to modify selected parts of their
298 own information, order and cancel services.  A web interface for new
299 customers.
300
301 Expand domain name stuff to house all domain information.  Export
302 named.boot/named.conf (primary and secondary) and named.{domain} files.
303 Add more registries (not just InterNIC's com org net edu)
304
305 Nice postscript paper invoices, rather than current ASCII invoices.
306
307 think about race-condititions in FS::Record and derived ->check ->insert
308 and so on, uid and username checks in svc_acct, etc.
309
310 Move to rsync over ssh file exportation rather than scp.
311
312 check 'n fix the proactive password checker. (cracklib?)
313
314 refunds of "BILL" payments: generate pseudo-check.
315
316 write batch senders and batch parsers for the different credit card processors
317 people use/
318 More CC processors/methods.
319
320 you should be able to fiddle the setup date in cust_pkg. (at least initially)
321
322 delete options in administration section
323
324 write a generic batch senders and batch parsers.
325
326 need a way to override svc_acct export on a per-machine basis; just use config files based on machine name i suppose; document that. (no, import desync_hosts
327 type stuff from cerkit)
328 ...
329 add a table with column of export services (passwd, shadow, master.passwd, .qmail file update, dns update, etc.) and rows machine groups and whether or not to export that (and any necessary parameters).  wasn't matt (vunderkid, not matt@michweb) working on this?  find him?  each machine goes in a group of its own as well as a group based on function.  add a table with only svcpart and machine group.  now, when you import from each machine, it can get its own accounts with one svcpart and universal accounts with another svcpart.  (though that does make the username duplicate checking more interesting)
330
331 you should be able to get column types as a method against an FS::Record object
332 as well as dbdef->table($table)->column($column)->type
333
334 move to perl module for fuzzy and soundex searching.
335
336 package view needs to list extraneous services; we need to prevent the
337 creation of them so this never happens (and mark it as such in the source)
338 (the creation problem should be fixed - though they will still happen if people
339 fsck around in the data manually, so list them anyway)
340
341 add attribute dictionary to fs-setup as a menu, plus analyze users file to
342 decide automatically
343
344 Check for and report on duplicate billing accounts (cust_main, though many
345 will have a need for these so probably don't disable them outright.)
346
347 create a ->warn as well as a ->check method for all FS::table classes?
348 (see above)
349
350 something to automate making a release and updating the web demo
351
352 export a debian-style (also redhat and?) /etc/group file aswell!
353
354 svc_acct_sm.import qmail import should pull in recipientmap people too.
355
356 .pm's like svc_acct.pm which need to do time-consuming things like ssh remotely
357 should fork and do them in a child.
358
359 i18n/l10n: take ALL messages and catalog them in english.txt or in database or something, so we can eventually go int'l.  int'l currency support would be a help aswell.
360
361 get some of { city, county, state, zip } from the missing bits if
362 possible (where can i get the data to do this?  usps.gov?)
363
364 additional interfaces (perltk?  java?)
365
366 Put the GPL notice in all files.
367
368 integrate w/IDEA's signup server
369
370 $cust_bill->owed database field to be eliminated, replaced by a method call
371 that calculates on the fly.  make sure to grep for ->(get|set)field('owed') 
372 same for cust_credit->credited
373
374 Export quota information.
375
376 move all configuration to a central place.  maybe in blob's in the
377 database.  maybe even things like the code to execute when a username is
378 changed can be in there, so less of the distributed scripts change between
379 different sites.
380
381 Implement setup and recurring fees as Safe perl expressions rather than
382 numbers, to allow for variable-rate services.  Backwards compatibility is
383 obtained because { 43 } in perl is still 43.  :)  Define API to pass
384 starting and ending dates and any other necessary data to expression
385 (fees are currently evaluated as Safe expressions but more work needs to
386 be done to define an opmask for various needs, write examples
387 (usage-based billing, etc.) and so on).
388 ...
389 Add the ability to modify the next billing date in cust_pkg, and take
390 appropriate action.  This will allow the implementation of pro-rate/1st of
391 the month billing as well as the ability to manually fiddle with
392 anniversary dates in cust_pkg, so you can sync a customer's anniversary
393 date even if you're using anniversary billing (manually or automatically).
394 (now with above, we need to have a way to automatically pro-rate /^(\d+)$/
395 charges - anything more complicated should figure it out itself given
396 starting and ending dates [document that!])
397 ...
398 Daily Radius log parsing into database; other logfile formats?
399 ...
400 Callbacks to enforce hourly limits on accounts (suspend until the end of
401 the billing period?), for those who limit customers rather than tack on
402 extra charges.
403
404 Flag packages (part_pkg) as taxable or non/taxable as some ISPs (for
405 example) need to charge tax on equipment but not service (separate flags
406 for setup and recurring fee... or perhaps a setup_tax, setup_notax,
407 recur_tax and recur_notax fees, and possibly something more flexible if
408 there is need).
409
410 Allow for a variable number of invoices for customers who need multiple
411 copies.
412
413 Add a mail alias service with table svc_acct (not domain mail aliasing
414 which is domain with svc_acct_sm)
415
416 (bring back from fsold) Change customer comment field from its current kludge to something more
417 workable.
418
419 Better work orders with more information.  Should eventually open a ticket
420 when we have such a thing.
421 edit/svc_wo.cgi
422 edit/process/svc_wo.cgi
423 Call tracking and trouble tickets.
424
425 More accoutability for complimentary accounts: approval, expiration, term
426 (no more than x months in advance) and notification.
427 Flag particular users (or all users, for that matter) as having their
428 passwords hidden and/or locked from users of Freeside (maybe need Freeside
429 security levels first?). 
430 ...
431 Better Freeside-level configurable access, for those ISP's who have
432 employees they can't trust.  Right now you're "stuck" with setting up
433 .htaccess stuff yourself.  This should really just be integrated. 
434
435 configuration/setup should get web interface
436 ...
437 /usr/local/etc/freeside should be configurable
438 ...
439 (probably as part of some automated installation process?)
440
441 This requires some serious magic in FS::Record:
442 ok, if date_type in fs-setup is to be something besides int,
443 now we need to create wrappers
444 for them so they behave identically across RDBMS's, ie date pops out as as
445 UNIX timestamp (or an object of some sort? maybe even a blessed $obj which
446 is a string not a hashref for backwards compatibility?) and so on. (remember
447 to treat '0' as Not a Date instead of 1/1/70.
448
449 Add Freeside-level transactions for RDBMS's which don't support
450 transcations?  (Currently we assume a minimal RDBMS which has no rollback,
451 transactions or atomic updates).  Or just require a RDBMS that supports
452 rollback and/or atomic updates and get rid of the work-arounds?  The /rdb
453 interface had this kludge on top of it but is a technical dead-end in most
454 other ways, unless it can gain an SQL parser and DBD interface.
455 ...
456 if i'm really bored, find the /rdb interface in fsold and port it to NoSQL,
457 and while I'm add it add interfaces for AnyDBM_File tied hash.. hmm.  Shouldn't
458 an FS::Record have something to do with a tied hash?  But we don't want
459 performance to go gaga... maybe something with commit to help out here?
460 ...
461 Ok: FS::Record gives you a tied hash, and you get methods for commit, etc.
462
463 Better automated comparison of our CC records with processors (CyberCash,
464 at least, has not always had 100% accuracy, though recent versions are
465 much better) 
466
467 Expect or other pty based login check, where we actually connect to a
468 terminal server or shell machine and test logging in as the user (if we
469 are keeping a cleartext password for that user)  (This is something tech
470 support often needs for new customers)
471
472 Use cust_main table for pre-sales tracking as well?
473
474 Automatic commision report and check generation via freq and prog (to
475 become a Safe perl expression) fields in agent table, and possibly others.
476
477 Database and add a mailed-out date and method for disk/CD mailing, so a
478 customer can call and you can say, "sent on xx/xx/xx via {US Mail, Fedex,
479 UPS, etc}" 
480
481 Inventory tracking for physical items such as routers (for sale or
482 lease... probably doesn't make a difference in the ordering... but if you
483 cancel a router lease the inventory should come back.  hmm.)
484
485 -- Matt's wishlist ---
486
487 From matt@michweb.net Fri Feb 20 16:39:53 1998
488 Date: Thu, 19 Feb 1998 23:20:11 -0500
489 From: Matt Simerson <matt@michweb.net>
490 Reply-To: quadran-developer@netgoth.com
491 To: quadran-developer@netgoth.com
492 Subject: Re: Welcome to quadran-developer
493
494 >Whats it based on and what is it supposed to do?  I'm interested, but
495 >unfortunatly, I don't have that much time to help on the project (I'm busily
496 >working on one of my own based around MySQL and Qt right now -- don't know
497 >if it will be GPL'ed or not yet -- we'll probably just use it in house since
498 >it is designed around our system)...
499
500 That's what I set out to find, but didn't find anything on the web site.
501 I'm looking for something that will do the following:
502
503 Single point of entry for users on a secure system:
504         Creates account on user (public) systems
505                 update /etc/passwd/master.passwd file
506                 update radius database (if necessary)
507         Set up up disk quotas (although I hacked adduser to do this)
508         Option for adding user to a mailing list(s)
509         Export of new user info to customizable report (for automated entry
510 into
511                 accounting software, etc...)
512
513 Automated billing:
514         Export credit card info for batch processing and have hooks built
515                 in for other forms of electronic processing.
516         Batch-Payment (apply payments from formatted text file).
517         Customizable reports for manual entry/importing into Accounting
518 software
519         Email or laser print invoices
520         Sanity checks credit card numbers before processing (code available)
521
522 Simple method for disabling an account.
523         Arbitrary Expiration Dates (on a given day, in x days)
524         Remove from radius.
525         Changing password to '*'
526         Virtual customers disabling dns, http server, log processing, etc..
527
528 Billing for different account types:
529         Dialup monthly flat rate. Prorates for partial months.
530         Dialup monthly flat rate for x hours + hourly usage.
531         Dialup email only
532         Email only accounts
533         Virtual Web accounts - w/multiple mailboxes
534         Leased line accounts
535         Disk space used over quota.
536         Tech support minimum + hourly charges
537         Other for misc stuff (modem, RAM, etc...)
538
539 Per user definable RADIUS attributes (ties in with above)
540         Fixed IP
541         Simultaneous Use
542         IP filters (for dialup email only)
543
544 Keep logs of modem usage generated daily from radius accounting logs stored
545 on multiple radius servers.
546
547 Keep logs of disk usage generated from quota.
548
549 Method of adding virtual domains to your system:
550         Automatically grabs an IP address from a preassigned pool.
551         Creates a domain.com database file from database fields
552         Updates /etc/named.conf or /etc/named.boot and reloads named.
553         Add's virtual.com to /etc/sendmail.cw or qmail control files.
554         Edits your web servers httpd.conf file and restarts http server.
555         An optional section for adding vif's can be added if the users OS
556                 supports adding them on the fly. Otherwise it's up to the end
557                 user. Make a hook that can run a custom script that the user
558                 tweaks for his system.
559         Update or create the config file your web stats analyzer needs. I've
560                 done this for analog (free) and http-analyze. Probably
561                 should only officially support analog and let users hack
562                 it to their hearts desire.
563 I've already written scripts that do most of the virtual web stuff on my
564 system...in bash. Shouldn't be hard for a perlmeister to convert. In fact,
565 as long as all the info was stored in the database (username, domain name,
566 and ip pool) this could easily just be run as an external script that the
567 user tweaks to match his system.
568
569 We use a great accounting software (M.Y.O.B) that does all the AP, AR,
570 Payroll, Tax stuff, and most everything else we could need. It's already
571 set up for the type of checks we have, etc, etc... I just need something to
572 do the billing part. I can import/export sales and payments directly once
573 the billing part is done. You can't write accounting software as good as
574 M.Y.O.B. for $120.
575
576