/************************* * * * * * * * * * * * * *************************** Copyright (c) 1999-2005 Ryan Bobko ryan@ostrich-emulators.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. ************************** * * * * * * * * * * * * **************************/ #include "cliimpplugin.h" #include "qhacc.h" #include "guiconstants.h" #include "qhacctable.h" #include "qhaccutils.h" #include #include #include #include #include #include using namespace std; // plugin factory calls extern "C" { QHaccPlugin * create(){ return new CLIImporter; } void destroy( CLIImporter * p ){ delete p; } } const CLIInfo CLIImporter::pinfo; CLIImporter::CLIImporter() : QHaccIOPlugin(){} CLIImporter::~CLIImporter(){} const PluginInfo& CLIImporter::info() const { return pinfo; } bool CLIImporter::checkHelp( int table, int, const QString& input ) const { if( input=="?" ){ bool useanums=engine->getBP( "USEANUMSFORNAMES" ); if( table==QC::ACCTT ){ // we want the accounts sorted by full name, like in the Chooser vector cols; cols.push_back( QC::APID ); cols.push_back( QC::ANAME ); cols.push_back( QC::AID ); cols.push_back( QC::ANUM ); const int NCOLS=4; QHaccResultSet orderer( NCOLS ); auto_ptr rs=engine->getAs( TableGet( cols ) ); uint rr=rs->rows(); for( uint i=0; iat( i ) ); QString str=a[1].gets(); uint pid=a[0].getu(); if( pid!=0 ) str=engine->getFNameOfA( pid )+QC::ASEP+str; TableRow r( NCOLS ); r.set( 0, pid ); r.set( 1, str ); r.set( 2, a[2] ); r.set( 3, a[3] ); orderer+=r; //cout<<"\t"< rs=engine->getLs(); for( uint i=0; irows(); i++ ){ TableRow l=rs->at( i ); cout<<"\t"<converter(); cout<<"QHacc Command Line Entry Plugin"<getBP( "HIDEJOURNALS" ) ){ auto_ptr rs=engine->getLs(); journal=rs->at( engine->getIP( "JOURNALINDEX" ) ); } else{ cout<<"Transaction Journal: "; QString lname=in.readLine(); while( !checkHelp( QC::JRNLT, 0, lname ) ){ cout<<"Transaction Journal: "; lname=in.readLine(); } journal=engine->getL( lname ); if( journal.isNull() ){ err="no journal: "+lname; return false; } } // get at least one account cout<<"Primary Account: "; QString aname=in.readLine(); while( !checkHelp( QC::ACCTT, 1, aname ) ){ cout<<"Primary Account: "; aname=in.readLine(); } TableRow acct=engine->getA( aname ); if( acct.isNull() ) err="no account: "+aname; else{ trans.set( QC::TLID, journal[QC::LID] ); trans.set( QC::TTYPE, TableCol( QC::REGULAR ) ); Split sp( QC::SCOLS ); sp.set( QC::SACCTID, acct[QC::AID] ); // if this account has an incremental number field, figure // out the highest number so far and increment it int highid=-1; if( acct[QC::ADEFAULTNUM]==GUIC::ACCTINCRSTR ){ uint rr=0; vector v; auto_ptr rs=engine->getXTForA( acct, TableGet( QC::XTNUM ), v, rr ); for( uint i=0; iat( i )[0].geti(); if( tti>=highid ) highid=tti+1; } trans.set( QC::TNUM, TableCol( highid ) ); } // now get the transaction information QString tnum=trans[QC::TNUM].gets(); cout<<"Transaction Number ["<getSP( "DATESEPARATOR" ); const int form=engine->getIP( "DATEFORMAT" ); cout<<"Transaction Date ["<getA( aname ); if( acct.isNull() ) cont=false; else{ QString tsum=conv.convert( 0-runningTotal, Engine, Engine ); cout<getFNameOfA( acct )<<" Sum["<addT( trans, splits, false ); loaded=( tid!=0 ); if( !loaded ) err="Could not add transaction"; } infile.close(); } return loaded; } bool CLIImporter::unmanned( const QString& home, QString& err ){ // this function should parse the cli and add a transaction accordingly // without any user interaction /** * CLI options are as follows: * --p payee * --n number * --m memo * --d date (defaults to today) * --j journal (defaults to visible journal) * --a account * --s sum (defaults to *) * --e recodate (defaults to XDATE) * * obviously multiple --a, --e and --s and be given. a split will not * be considered complete until a sum is given for each account * (the last account will implicitly use a * as its sum) * any option can have a space or not have a space before the argument **/ const QString SEP=engine->getSP( "DATESEPARATOR" ); const int FMT=engine->getIP( "DATEFORMAT" ); Transaction t( QC::TCOLS ); const TableCol TID( engine->max( TRANSACTIONS, QC::TID ).getu()+1 ); t.set( QC::TID, TID ); auto_ptr rs=engine->getLs(); Journal journal=rs->at( engine->getIP( "JOURNALINDEX" ) ); t.set( QC::TLID, journal[QC::LID] ); t.set( QC::TDATE, QDate::currentDate() ); t.set( QC::TTYPE, QC::REGULAR ); uint sid=engine->max( SPLITS, QC::SID ).getu()+1; QHaccTable splits( QC::SCOLS, QC::SCOLTYPES ); Split cursplit; QStringList args=QStringList::split( "--", home ); for( QStringList::Iterator it=args.begin(); it!=args.end(); ++it ) { QString option=( *it ).left( 1 ); QString arg=( *it ).mid( 1 ).simplifyWhiteSpace(); if( option=="p" ) t.set( QC::TPAYEE, arg ); else if( option=="n" ) t.set( QC::TNUM, arg ); else if( option=="m" ) t.set( QC::TMEMO, arg ); else if( option=="j" ){ Journal j=engine->getL( arg ); if( j.isNull() ){ err="no journal: "+arg; return false; } t.set( QC::TLID, j[QC::LID] ); } else if( option=="d" ) t.set( QC::TDATE, Utils::dateFromString( arg, SEP, FMT ) ); else if( option=="a" ){ if( !cursplit.isNull() ) splits+=cursplit; cursplit=Split( QC::SCOLS ); cursplit.set( QC::SID, sid++ ); cursplit.set( QC::STID, TID ); // if an invalid account is entered, quit immediately Account a=engine->getA( arg ); if( a.isNull() ){ err="no account: "+arg; return false; } cursplit.set( QC::SACCTID, a[QC::AID] ); cursplit.set( QC::SSUM, "*" ); cursplit.set( QC::SRECODATE, QC::XDATE ); cursplit.set( QC::SRECO, QC::NREC ); } else if( option=="e" ){ if( cursplit.isNull() ){ err="must specify a split before a reconcile date"; return false; } cursplit.set( QC::SRECODATE, Utils::dateFromString( arg, SEP, FMT ) ); cursplit.set( QC::SRECO, QC::YREC ); } else if( option=="s" ){ if( cursplit.isNull() ){ err="must specify an account before a split"; return false; } cursplit.set( QC::SSUM, arg ); } cout<<"option: "<addT( t, splits )!=0 ); } // everything this plugin does, it does during the load bool CLIImporter::exprt( QHaccResultSet * ){ return true; } // this is just an importer, so we don't need these functions, // but they must be defined to instatiate this class bool CLIImporter::imprt( QHaccResultSet * ){ return false; } bool CLIImporter::save( QString& ){ return false; } CLIInfo::CLIInfo(){ raw=true; guisel=false; description="Command Line Entry"; stubby="CLI"; }