X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=src%2Fserver%2Fdispense.c;h=01b53c8338f712c43e54374740fad9fffc83fb6b;hb=88dc83a1cdc8df8d74078f1d41726095d5a26d61;hp=137aab7023fabf89b9d06e962ea36f60808e442f;hpb=0a4c98ea7934d4fb61121fb8cf8c4d94f973b950;p=tpg%2Fopendispense2.git diff --git a/src/server/dispense.c b/src/server/dispense.c index 137aab7..01b53c8 100644 --- a/src/server/dispense.c +++ b/src/server/dispense.c @@ -2,6 +2,12 @@ */ #include "common.h" #include +#include +#include + + int _GetMinBalance(int Account); + int _CanTransfer(int Source, int Destination, int Ammount); + int _Transfer(int Source, int Destination, int Ammount, const char *Reason); // === CODE === /** @@ -11,10 +17,17 @@ */ int DispenseItem(int ActualUser, int User, tItem *Item) { - int ret; + int ret, salesAcct; tHandler *handler; char *username, *actualUsername; - char *reason; + + salesAcct = Bank_GetAcctByName(COKEBANK_SALES_ACCT); + + // Check if the user can afford it + if( Item->Price && !_CanTransfer(User, salesAcct, Item->Price) ) + { + return 2; // 2: No balance + } handler = Item->Handler; @@ -23,33 +36,34 @@ int DispenseItem(int ActualUser, int User, tItem *Item) ret = handler->CanDispense( User, Item->ID ); if(ret) return 1; // 1: Unable to dispense } - - // Subtract the balance - reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name); - if( !reason ) reason = Item->Name; // TODO: Should I instead return an error? - ret = Bank_Transfer( User, Bank_GetUserID(COKEBANK_SALES_ACCT), Item->Price, reason); - free(reason); - if(ret) return 2; // 2: No balance // Get username for debugging - username = Bank_GetUserName(User); + username = Bank_GetAcctName(User); // Actually do the dispense if( handler->DoDispense ) { ret = handler->DoDispense( User, Item->ID ); if(ret) { - Log_Error("Dispense failed after deducting cost (%s dispensing %s - %ic)", + Log_Error("Dispense failed (%s dispensing '%s' - %ic)", username, Item->Name, Item->Price); - Bank_Transfer( Bank_GetUserID(COKEBANK_SALES_ACCT), User, Item->Price, "rollback" ); free( username ); - return -1; // 1: Unkown Error again + return -1; // 1: Unknown Error again } } - actualUsername = Bank_GetUserName(ActualUser); + // Take away money + if( Item->Price ) + { + char *reason; + reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name); + _Transfer( User, salesAcct, Item->Price, reason ); + free(reason); + } + + actualUsername = Bank_GetAcctName(ActualUser); // And log that it happened - Log_Info("dispense '%s' (%s:%i) for %s by %s [cost %i, balance %i cents]", + Log_Info("dispense '%s' (%s:%i) for %s by %s [cost %i, balance %i]", Item->Name, handler->Name, Item->ID, username, actualUsername, Item->Price, Bank_GetBalance(User) ); @@ -59,6 +73,39 @@ int DispenseItem(int ActualUser, int User, tItem *Item) return 0; // 0: EOK } +/** + * \brief Refund a dispense + */ +int DispenseRefund(int ActualUser, int DestUser, tItem *Item, int OverridePrice) +{ + int ret; + int src_acct, price; + char *username, *actualUsername; + + src_acct = Bank_GetAcctByName(COKEBANK_SALES_ACCT); + + if( OverridePrice > 0 ) + price = OverridePrice; + else + price = Item->Price; + + ret = _Transfer( src_acct, DestUser, price, "Refund"); + if(ret) return ret; + + username = Bank_GetAcctName(DestUser); + actualUsername = Bank_GetAcctName(ActualUser); + + Log_Info("refund '%s' (%s:%i) to %s by %s [cost %i, balance %i]", + Item->Name, Item->Handler->Name, Item->ID, + username, actualUsername, price, Bank_GetBalance(DestUser) + ); + + free(username); + free(actualUsername); + + return 0; +} + /** * \brief Give money from one user to another */ @@ -70,17 +117,18 @@ int DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const c if( Ammount < 0 ) return 1; // Um... negative give? Not on my watch! - ret = Bank_Transfer( SrcUser, DestUser, Ammount, ReasonGiven ); + ret = _Transfer( SrcUser, DestUser, Ammount, ReasonGiven ); if(ret) return 2; // No Balance - srcName = Bank_GetUserName(SrcUser); - dstName = Bank_GetUserName(DestUser); - actualUsername = Bank_GetUserName(ActualUser); + actualUsername = Bank_GetAcctName(ActualUser); + srcName = Bank_GetAcctName(SrcUser); + dstName = Bank_GetAcctName(DestUser); - Log_Info("give %i to %s from %s by %s (%s) [balances %i, %i]", - Ammount, dstName, srcName, actualUsername, ReasonGiven, - Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser) + Log_Info("give %i to %s from %s by %s [balances %i, %i] - %s", + Ammount, dstName, srcName, actualUsername, + Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser), + ReasonGiven ); free(srcName); @@ -90,22 +138,59 @@ int DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const c return 0; } +/** + * \brief Move money from one user to another (Admin Only) + */ +int DispenseTransfer(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven) +{ + int ret; + char *actualUsername; + char *srcName, *dstName; + + // Make sure the user is an admin + if( !(Bank_GetFlags(ActualUser) & USER_FLAG_ADMIN) ) + return 1; + + ret = _Transfer( SrcUser, DestUser, Ammount, ReasonGiven ); + if(ret) return 2; // No Balance + + + actualUsername = Bank_GetAcctName(ActualUser); + srcName = Bank_GetAcctName(SrcUser); + dstName = Bank_GetAcctName(DestUser); + + Log_Info("move %i to %s from %s by %s [balances %i, %i] - %s", + Ammount, dstName, srcName, actualUsername, + Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser), + ReasonGiven + ); + + free(srcName); + free(dstName); + free(actualUsername); + + return 0; +} /** * \brief Add money to an account */ -int DispenseAdd(int User, int ByUser, int Ammount, const char *ReasonGiven) +int DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven) { int ret; char *dstName, *byName; - ret = Bank_Transfer( Bank_GetUserID(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven ); +#if DISPENSE_ADD_BELOW_MIN + ret = _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven ); +#else + ret = Bank_Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven ); +#endif if(ret) return 2; - byName = Bank_GetUserName(ByUser); - dstName = Bank_GetUserName(User); + byName = Bank_GetAcctName(ActualUser); + dstName = Bank_GetAcctName(User); - Log_Info("add %i to %s by %s (%s) [balance %i]", - Ammount, dstName, byName, ReasonGiven, Bank_GetBalance(User) + Log_Info("add %i to %s by %s [balance %i] - %s", + Ammount, dstName, byName, Bank_GetBalance(User), ReasonGiven ); free(byName); @@ -113,3 +198,105 @@ int DispenseAdd(int User, int ByUser, int Ammount, const char *ReasonGiven) return 0; } + +int DispenseSet(int ActualUser, int User, int Balance, const char *ReasonGiven) +{ + int curBal = Bank_GetBalance(User); + char *byName, *dstName; + + _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Balance-curBal, ReasonGiven ); + + byName = Bank_GetAcctName(ActualUser); + dstName = Bank_GetAcctName(User); + + Log_Info("set balance of %s to %i by %s [balance %i] - %s", + dstName, Balance, byName, Bank_GetBalance(User), ReasonGiven + ); + + free(byName); + free(dstName); + + return 0; +} + +/** + * \brief Donate money to the club + */ +int DispenseDonate(int ActualUser, int User, int Ammount, const char *ReasonGiven) +{ + int ret; + char *srcName, *byName; + + if( Ammount < 0 ) return 2; + + ret = _Transfer( User, Bank_GetAcctByName(COKEBANK_DEBT_ACCT), Ammount, ReasonGiven ); + if(ret) return 2; + + byName = Bank_GetAcctName(ActualUser); + srcName = Bank_GetAcctName(User); + + Log_Info("donate %i from %s by %s [balance %i] - %s", + Ammount, srcName, byName, Bank_GetBalance(User), ReasonGiven + ); + + free(byName); + free(srcName); + + return 0; +} + +// --- Internal Functions --- +int _GetMinBalance(int Account) +{ + int flags = Bank_GetFlags(Account); + + // Evil little piece of HACK: + // root's balance cannot be changed by any of the above functions + // - Stops dispenses as root by returning insufficent balance. + { + char *username = Bank_GetAcctName(Account); + if( strcmp(username, "root") == 0 ) + { + free(username); + return INT_MAX; + } + free(username); + } + + // - Internal accounts have no lower bound + if( flags & USER_FLAG_INTERNAL ) return INT_MIN; + + // Admin to -$50 +// if( flags & USER_FLAG_ADMIN ) return -5000; + + // Coke to -$20 +// if( flags & USER_FLAG_COKE ) return -2000; + + // Anyone else, non-negative + return 0; +} + +/** + * \brief Check if a transfer is possible + */ +int _CanTransfer(int Source, int Destination, int Ammount) +{ + if( Ammount > 0 ) + { + if( Bank_GetBalance(Source) - Ammount < _GetMinBalance(Source) ) + return 0; + } + else + { + if( Bank_GetBalance(Destination) + Ammount < _GetMinBalance(Destination) ) + return 0; + } + return 1; +} + +int _Transfer(int Source, int Destination, int Ammount, const char *Reason) +{ + if( !_CanTransfer(Source, Destination, Ammount) ) + return 1; + return Bank_Transfer(Source, Destination, Ammount, Reason); +}