8 int _GetMinBalance(int Account);
9 int _CanTransfer(int Source, int Destination, int Ammount);
10 int _Transfer(int Source, int Destination, int Ammount, const char *Reason);
14 * \brief Dispense an item for a user
16 * The core of the dispense system, I kinda like it :)
18 int DispenseItem(int ActualUser, int User, tItem *Item)
22 char *username, *actualUsername;
24 salesAcct = Bank_GetAcctByName(COKEBANK_SALES_ACCT);
26 // Check if the user can afford it
27 if( Item->Price && !_CanTransfer(User, salesAcct, Item->Price) )
29 return 2; // 2: No balance
32 handler = Item->Handler;
34 // Check if the dispense is possible
35 if( handler->CanDispense ) {
36 ret = handler->CanDispense( User, Item->ID );
37 if(ret) return 1; // 1: Unable to dispense
40 // Get username for debugging
41 username = Bank_GetAcctName(User);
43 // Actually do the dispense
44 if( handler->DoDispense ) {
45 ret = handler->DoDispense( User, Item->ID );
47 Log_Error("Dispense failed (%s dispensing '%s' - %ic)",
48 username, Item->Name, Item->Price);
50 return -1; // 1: Unknown Error again
58 reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name);
59 _Transfer( User, salesAcct, Item->Price, reason );
63 actualUsername = Bank_GetAcctName(ActualUser);
65 // And log that it happened
66 Log_Info("dispense '%s' (%s:%i) for %s by %s [cost %i, balance %i]",
67 Item->Name, handler->Name, Item->ID,
68 username, actualUsername, Item->Price, Bank_GetBalance(User)
72 free( actualUsername );
77 * \brief Refund a dispense
79 int DispenseRefund(int ActualUser, int DestUser, tItem *Item, int OverridePrice)
83 char *username, *actualUsername;
85 src_acct = Bank_GetAcctByName(COKEBANK_SALES_ACCT);
87 if( OverridePrice > 0 )
88 price = OverridePrice;
92 ret = _Transfer( src_acct, DestUser, price, "Refund");
95 username = Bank_GetAcctName(DestUser);
96 actualUsername = Bank_GetAcctName(ActualUser);
98 Log_Info("refund '%s' (%s:%i) to %s by %s [cost %i, balance %i]",
99 Item->Name, Item->Handler->Name, Item->ID,
100 username, actualUsername, price, Bank_GetBalance(DestUser)
104 free(actualUsername);
110 * \brief Give money from one user to another
112 int DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven)
115 char *actualUsername;
116 char *srcName, *dstName;
118 if( Ammount < 0 ) return 1; // Um... negative give? Not on my watch!
120 ret = _Transfer( SrcUser, DestUser, Ammount, ReasonGiven );
121 if(ret) return 2; // No Balance
124 actualUsername = Bank_GetAcctName(ActualUser);
125 srcName = Bank_GetAcctName(SrcUser);
126 dstName = Bank_GetAcctName(DestUser);
128 Log_Info("give %i to %s from %s by %s [balances %i, %i] - %s",
129 Ammount, dstName, srcName, actualUsername,
130 Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser),
136 free(actualUsername);
142 * \brief Move money from one user to another (Admin Only)
144 int DispenseTransfer(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven)
147 char *actualUsername;
148 char *srcName, *dstName;
150 // Make sure the user is an admin
151 if( !(Bank_GetFlags(ActualUser) & USER_FLAG_ADMIN) )
154 ret = _Transfer( SrcUser, DestUser, Ammount, ReasonGiven );
155 if(ret) return 2; // No Balance
158 actualUsername = Bank_GetAcctName(ActualUser);
159 srcName = Bank_GetAcctName(SrcUser);
160 dstName = Bank_GetAcctName(DestUser);
162 Log_Info("move %i to %s from %s by %s [balances %i, %i] - %s",
163 Ammount, dstName, srcName, actualUsername,
164 Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser),
170 free(actualUsername);
175 * \brief Add money to an account
177 int DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven)
180 char *dstName, *byName;
182 #if DISPENSE_ADD_BELOW_MIN
183 ret = _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
185 ret = Bank_Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
189 byName = Bank_GetAcctName(ActualUser);
190 dstName = Bank_GetAcctName(User);
192 Log_Info("add %i to %s by %s [balance %i] - %s",
193 Ammount, dstName, byName, Bank_GetBalance(User), ReasonGiven
202 int DispenseSet(int ActualUser, int User, int Balance, const char *ReasonGiven)
204 int curBal = Bank_GetBalance(User);
205 char *byName, *dstName;
207 _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Balance-curBal, ReasonGiven );
209 byName = Bank_GetAcctName(ActualUser);
210 dstName = Bank_GetAcctName(User);
212 Log_Info("set balance of %s to %i by %s [balance %i] - %s",
213 dstName, Balance, byName, Bank_GetBalance(User), ReasonGiven
223 * \brief Donate money to the club
225 int DispenseDonate(int ActualUser, int User, int Ammount, const char *ReasonGiven)
228 char *srcName, *byName;
230 if( Ammount < 0 ) return 2;
232 ret = _Transfer( User, Bank_GetAcctByName(COKEBANK_DEBT_ACCT), Ammount, ReasonGiven );
235 byName = Bank_GetAcctName(ActualUser);
236 srcName = Bank_GetAcctName(User);
238 Log_Info("donate %i from %s by %s [balance %i] - %s",
239 Ammount, srcName, byName, Bank_GetBalance(User), ReasonGiven
248 // --- Internal Functions ---
249 int _GetMinBalance(int Account)
251 int flags = Bank_GetFlags(Account);
253 // Evil little piece of HACK:
254 // root's balance cannot be changed by any of the above functions
255 // - Stops dispenses as root by returning insufficent balance.
257 char *username = Bank_GetAcctName(Account);
258 if( strcmp(username, "root") == 0 )
266 // - Internal accounts have no lower bound
267 if( flags & USER_FLAG_INTERNAL ) return INT_MIN;
270 // if( flags & USER_FLAG_ADMIN ) return -5000;
273 // if( flags & USER_FLAG_COKE ) return -2000;
275 // Anyone else, non-negative
280 * \brief Check if a transfer is possible
282 int _CanTransfer(int Source, int Destination, int Ammount)
286 if( Bank_GetBalance(Source) - Ammount < _GetMinBalance(Source) )
291 if( Bank_GetBalance(Destination) + Ammount < _GetMinBalance(Destination) )
297 int _Transfer(int Source, int Destination, int Ammount, const char *Reason)
299 if( !_CanTransfer(Source, Destination, Ammount) )
301 return Bank_Transfer(Source, Destination, Ammount, Reason);