7 int _GetMinBalance(int Account);
8 int _Transfer(int Source, int Destination, int Ammount, const char *Reason);
12 * \brief Dispense an item for a user
14 * The core of the dispense system, I kinda like it :)
16 int DispenseItem(int ActualUser, int User, tItem *Item)
20 char *username, *actualUsername;
23 handler = Item->Handler;
25 // Check if the dispense is possible
26 if( handler->CanDispense ) {
27 ret = handler->CanDispense( User, Item->ID );
28 if(ret) return 1; // 1: Unable to dispense
31 // Subtract the balance
34 reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name);
35 if( !reason ) reason = Item->Name; // TODO: Should I instead return an error?
36 ret = _Transfer( User, Bank_GetAcctByName(COKEBANK_SALES_ACCT), Item->Price, reason);
38 if(ret) return 2; // 2: No balance
41 // Get username for debugging
42 username = Bank_GetAcctName(User);
44 // Actually do the dispense
45 if( handler->DoDispense ) {
46 ret = handler->DoDispense( User, Item->ID );
48 Log_Error("Dispense failed after deducting cost (%s dispensing %s - %ic)",
49 username, Item->Name, Item->Price);
51 _Transfer( Bank_GetAcctByName(COKEBANK_SALES_ACCT), User, Item->Price, "rollback" );
53 return -1; // 1: Unkown Error again
57 actualUsername = Bank_GetAcctName(ActualUser);
59 // And log that it happened
60 Log_Info("dispense '%s' (%s:%i) for %s by %s [cost %i, balance %i]",
61 Item->Name, handler->Name, Item->ID,
62 username, actualUsername, Item->Price, Bank_GetBalance(User)
66 free( actualUsername );
71 * \brief Give money from one user to another
73 int DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven)
77 char *srcName, *dstName;
79 if( Ammount < 0 ) return 1; // Um... negative give? Not on my watch!
81 ret = _Transfer( SrcUser, DestUser, Ammount, ReasonGiven );
82 if(ret) return 2; // No Balance
85 actualUsername = Bank_GetAcctName(ActualUser);
86 srcName = Bank_GetAcctName(SrcUser);
87 dstName = Bank_GetAcctName(DestUser);
89 Log_Info("give %i to %s from %s by %s [balances %i, %i] - %s",
90 Ammount, dstName, srcName, actualUsername,
91 Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser),
103 * \brief Add money to an account
105 int DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven)
108 char *dstName, *byName;
110 ret = _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
113 byName = Bank_GetAcctName(ActualUser);
114 dstName = Bank_GetAcctName(User);
116 Log_Info("add %i to %s by %s [balance %i] - %s",
117 Ammount, dstName, byName, Bank_GetBalance(User), ReasonGiven
127 * \brief Donate money to the club
129 int DispenseDonate(int ActualUser, int User, int Ammount, const char *ReasonGiven)
132 char *srcName, *byName;
134 if( Ammount < 0 ) return 2;
136 ret = _Transfer( User, Bank_GetAcctByName(COKEBANK_DEBT_ACCT), Ammount, ReasonGiven );
139 byName = Bank_GetAcctName(ActualUser);
140 srcName = Bank_GetAcctName(User);
142 Log_Info("donate %i from %s by %s [balance %i] - %s",
143 Ammount, srcName, byName, Bank_GetBalance(User), ReasonGiven
152 // --- Internal Functions ---
153 int _GetMinBalance(int Account)
155 int flags = Bank_GetFlags(Account);
157 // - Internal accounts have no lower bound
158 if( flags & USER_FLAG_INTERNAL ) return INT_MIN;
161 if( flags & USER_FLAG_ADMIN ) return -1000;
164 if( flags & USER_FLAG_COKE ) return -500;
166 // Anyone else, non-negative
170 int _Transfer(int Source, int Destination, int Ammount, const char *Reason)
174 if( Bank_GetBalance(Source) + Ammount < _GetMinBalance(Source) )
179 if( Bank_GetBalance(Destination) - Ammount < _GetMinBalance(Destination) )
183 return Bank_Transfer(Source, Destination, Ammount, Reason);