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 // KNOWN HACK: Naming a slot "dead" disables it
35 if( strcmp(Item->Name, "dead") == 0 )
38 // Check if the dispense is possible
39 if( handler->CanDispense ) {
40 ret = handler->CanDispense( User, Item->ID );
41 if(ret) return 1; // 1: Unable to dispense
44 // Get username for debugging
45 username = Bank_GetAcctName(User);
47 // Actually do the dispense
48 if( handler->DoDispense ) {
49 ret = handler->DoDispense( User, Item->ID );
51 Log_Error("Dispense failed (%s dispensing %s:%i '%s')",
52 username, Item->Name, Item->Handler->Name, Item->ID);
54 return -1; // 1: Unknown Error again
62 reason = mkstr("Dispense - %s:%i %s", handler->Name, Item->ID, Item->Name);
63 _Transfer( User, salesAcct, Item->Price, reason );
67 actualUsername = Bank_GetAcctName(ActualUser);
69 // And log that it happened
70 Log_Info("dispense '%s' (%s:%i) for %s by %s [cost %i, balance %i]",
71 Item->Name, handler->Name, Item->ID,
72 username, actualUsername, Item->Price, Bank_GetBalance(User)
76 free( actualUsername );
81 * \brief Refund a dispense
83 int DispenseRefund(int ActualUser, int DestUser, tItem *Item, int OverridePrice)
87 char *username, *actualUsername;
89 src_acct = Bank_GetAcctByName(COKEBANK_SALES_ACCT);
91 if( OverridePrice > 0 )
92 price = OverridePrice;
96 ret = _Transfer( src_acct, DestUser, price, "Refund");
99 username = Bank_GetAcctName(DestUser);
100 actualUsername = Bank_GetAcctName(ActualUser);
102 Log_Info("refund '%s' (%s:%i) to %s by %s [cost %i, balance %i]",
103 Item->Name, Item->Handler->Name, Item->ID,
104 username, actualUsername, price, Bank_GetBalance(DestUser)
108 free(actualUsername);
114 * \brief Give money from one user to another
116 int DispenseGive(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven)
119 char *actualUsername;
120 char *srcName, *dstName;
122 if( Ammount < 0 ) return 1; // Um... negative give? Not on my watch!
124 ret = _Transfer( SrcUser, DestUser, Ammount, ReasonGiven );
125 if(ret) return 2; // No Balance
128 actualUsername = Bank_GetAcctName(ActualUser);
129 srcName = Bank_GetAcctName(SrcUser);
130 dstName = Bank_GetAcctName(DestUser);
132 Log_Info("give %i from %s to %s by %s [balances %i, %i] - %s",
133 Ammount, srcName, dstName, actualUsername,
134 Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser),
140 free(actualUsername);
147 * \brief Move money from one user to another (Admin Only)
149 int DispenseTransfer(int ActualUser, int SrcUser, int DestUser, int Ammount, const char *ReasonGiven)
152 char *actualUsername;
153 char *srcName, *dstName;
155 // Make sure the user is an admin
156 if( !(Bank_GetFlags(ActualUser) & USER_FLAG_ADMIN) )
159 ret = _Transfer( SrcUser, DestUser, Ammount, ReasonGiven );
160 if(ret) return 2; // No Balance
163 actualUsername = Bank_GetAcctName(ActualUser);
164 srcName = Bank_GetAcctName(SrcUser);
165 dstName = Bank_GetAcctName(DestUser);
167 Log_Info("move %i from %s to %s by %s [balances %i, %i] - %s",
168 Ammount, srcName, dstName, actualUsername,
169 Bank_GetBalance(SrcUser), Bank_GetBalance(DestUser),
175 free(actualUsername);
182 * \brief Add money to an account
184 int DispenseAdd(int ActualUser, int User, int Ammount, const char *ReasonGiven)
187 char *dstName, *byName;
189 #if DISPENSE_ADD_BELOW_MIN
190 ret = _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
192 ret = Bank_Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Ammount, ReasonGiven );
196 byName = Bank_GetAcctName(ActualUser);
197 dstName = Bank_GetAcctName(User);
199 Log_Info("add %i to %s by %s [balance %i] - %s",
200 Ammount, dstName, byName, Bank_GetBalance(User), ReasonGiven
209 int DispenseSet(int ActualUser, int User, int Balance, const char *ReasonGiven)
211 int curBal = Bank_GetBalance(User);
212 char *byName, *dstName;
214 _Transfer( Bank_GetAcctByName(COKEBANK_DEBT_ACCT), User, Balance-curBal, ReasonGiven );
216 byName = Bank_GetAcctName(ActualUser);
217 dstName = Bank_GetAcctName(User);
219 Log_Info("set balance of %s to %i by %s [balance %i] - %s",
220 dstName, Balance, byName, Bank_GetBalance(User), ReasonGiven
230 * \brief Donate money to the club
232 int DispenseDonate(int ActualUser, int User, int Ammount, const char *ReasonGiven)
235 char *srcName, *byName;
237 if( Ammount < 0 ) return 2;
239 ret = _Transfer( User, Bank_GetAcctByName(COKEBANK_DEBT_ACCT), Ammount, ReasonGiven );
242 byName = Bank_GetAcctName(ActualUser);
243 srcName = Bank_GetAcctName(User);
245 Log_Info("donate %i from %s by %s [balance %i] - %s",
246 Ammount, srcName, byName, Bank_GetBalance(User), ReasonGiven
255 int DispenseUpdateItem(int User, tItem *Item, const char *NewName, int NewPrice)
260 if( NewPrice < 0 ) return 2;
261 if( !Item ) return 2;
262 if( strlen(NewName) < 1 ) return 2;
266 Item->Name = strdup(NewName);
267 Item->Price = NewPrice;
269 username = Bank_GetAcctName(User);
271 Log_Info("item %s:%i updated to '%s' %i by %s",
272 Item->Handler->Name, Item->ID,
273 NewName, NewPrice, username
284 // --- Internal Functions ---
285 int _GetMinBalance(int Account)
287 int flags = Bank_GetFlags(Account);
289 // Evil little piece of HACK:
290 // root's balance cannot be changed by any of the above functions
291 // - Stops dispenses as root by returning insufficent balance.
293 char *username = Bank_GetAcctName(Account);
294 if( strcmp(username, "root") == 0 )
302 // - Internal accounts have no lower bound
303 if( flags & USER_FLAG_INTERNAL ) return INT_MIN;
306 // if( flags & USER_FLAG_ADMIN ) return -5000;
309 // if( flags & USER_FLAG_COKE ) return -2000;
311 // Anyone else, non-negative
316 * \brief Check if a transfer is possible
318 int _CanTransfer(int Source, int Destination, int Ammount)
322 if( Bank_GetBalance(Source) - Ammount < _GetMinBalance(Source) )
327 if( Bank_GetBalance(Destination) + Ammount < _GetMinBalance(Destination) )
333 int _Transfer(int Source, int Destination, int Ammount, const char *Reason)
335 if( !_CanTransfer(Source, Destination, Ammount) )
337 return Bank_Transfer(Source, Destination, Ammount, Reason);