-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathfirm.cpp
More file actions
520 lines (450 loc) · 16.5 KB
/
firm.cpp
File metadata and controls
520 lines (450 loc) · 16.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
// *** FUNDAMENTALS ***
//
// The notional 'government-owned' firm is the only firm that is created
// initially and serves as a target for government spending. Other firms come
// into existence depending on economic conditions. The government-owned firm is
// the civil service, the military and public services or other enterprises that
// are entirely funded by the government.
//
// Suppose a private firm (or all private firms taken together) produce goods
// and services to the value of n CUs (currency units). If all their stock is
// sold (the best case scenario) they will receive payments of n CUs and this is
// the most they can pay their employees in wages without drawing on credit.
// However, their employees will have to return some of this money to the
// government in taxes and will not therefore be able to buy all the stock. This
// means there will be less money available to pay out in wages next time, and
// even less stock will be produced. Eventually the company will have to get rid
// of its employees and go out of business.
//
// This is avoided is by the injection of new money through the following
// mechanisms: increasing credit from the banks, payment of benefits to the
// unemployed by the government using new money (which means that in part the
// government finances employment via the unemployed) direct purchases from
// private firms by the government (using new money), and purchases by employees
// of the notional government-owned firm. Note that all these mechanisms rely in
// different ways on the ceation of new money by the governmwent.
// ***
#include "account.h"
#include <cassert>
#include <QtMath>
#include <QDebug>
Firm::Firm(Domain *domain, bool state_supported) : Account(domain)
{
_state_supported = state_supported;
}
void Firm::init()
{
/*
* Reset non-cumulative variables
*/
wages_paid = 0;
sales_tax_paid = 0;
sales_receipts = 0;
num_hired = 0;
num_fired = 0;
bonuses_paid = 0;
investment= 0;
num_just_fired = 0;
productivity = 1.0;
_dedns = 0.0;
_state_supported = false;
employees.clear();
}
bool Firm::isGovernmentSupported()
{
return _state_supported;
}
void Firm::trigger(int period)
{
if (period > last_triggered)
{
last_triggered = period;
// TODO: This needs sorting out properly!
if (!_state_supported)
{
// Pay interest on bank loans.
// TODO: At present we never pay off the loan. We should have a
// parameter that indicates the factor by which the balance has to
// exceed the outstanding loan before we will repay it. Or
// something...
double interest = owed_to_bank * interest_rate;
// If interest is greater than balance we'll just skip the payment
// and hope for better luck next time. A bank is unlikely to
// foreclose unless this happens a lot...
if (interest > 0 && interest <= balance)
{
//qDebug() << "Firm::trigger(): paying loan interest of" << interest;
if (!transferSafely(_bank, interest, this))
{
qDebug() << "Firm::trigger(): failed to transfer interest to bank";
}
}
else if (interest < 1.0 && owed_to_bank > 0)
{
qDebug() << "Firm::trigger(): adding interest of"
<< interest
<< "to loan";
owed_to_bank += interest;
}
}
if (employees.count() > 0)
{
wages_paid += payWages();
balance -= wages_paid;
}
}
}
double Firm::payWages()
{
double amt_paid = 0;
num_just_fired = 0;
int dedns_rate = _domain->getPreTaxDedns();
int num_employees = static_cast<int> (employees.count());
for (int i = 0; i < num_employees; i++)
{
Worker *w = employees[i];
double wage_due = w->agreed_wage;
double dedns = (dedns_rate * wage_due) / 100;
double funds_available = getBalance();
bool ok_to_pay = false;
if (!isGovernment() && (funds_available /* - amt_paid */ < wage_due /* + dedns */))
{
/*
* The firm doesn't have enough money in its account to pay all
* the wages due.
*/
double shortfall = wage_due /* + dedns */ - funds_available /* + amt_paid */;
if (isGovernmentSupported())
{
/*
* Get additional funds from government -- this needs
* expanding. Government must advance fund (HPM) to the
* firm's bank account, that account should then be debited
* and the payee's bank account credited. To do this
* properly we need to set up two transfer mechanisms -- one
* from government to the firm's bank (HPM) followed by a
* credit to the firms own account, and the other an
* uncleared transfer from the firm's account to the
* rmployee's account. Here we short circuit the process
* but to exactly the same effect except that the funds are
* in effect cleared immediately.
*/
_domain->government()->debit(this, shortfall);
// Transfer the funds to the firm
qDebug() << "crediting" << shortfall;
credit(shortfall, this);
ok_to_pay = true;
}
else
{
/*
* Possibly request a loan from the bank, depending on
* policy. Policy is determined by getLoanProb(), which
* returns an integer from 0 (= never) to 4 (= always).
*/
if (qrand() % 4 < _domain->getLoanProb())
{
// Apply a bank loan to cover the shortfall
_bank->lend(shortfall, _domain->getBusRate(), this);
ok_to_pay = true;
}
}
}
else
{
ok_to_pay = true;
}
if (ok_to_pay)
{
/*
* Pay the full amount of wages to the employee
*/
// qDebug() << "crediting" << wage_due;
employees[i]->credit(wage_due - dedns, this);
/*
* Pay deductions straight back to the government.
*/
// qDebug() << "crediting" << dedns;
_domain->government()->credit(dedns, this);
// amt_paid += wage_due + dedns;
_dedns += dedns;
}
else
{
//Q_ASSERT_X(isGovernmentSupported(), "Firm::payWages",
// "Firm is government supported");
// Not able to pay this worker so fire instead
fire(employees[i]);
}
}
return amt_paid; // so caller can update balance
}
//double Firm::payBonuses(double amount)
//{
// qDebug() << "Firm::payBonuses (" << amount << ") called";
// Q_ASSERT(false);
//}
/*
* This function is likely to be significantly slower than fire(int ix)
*/
void Firm::fire(Worker *w)
{
employees.removeOne(w);
w->employer = nullptr;
num_fired++;
}
/*
* Faster version for use when ix is known
*/
void Firm::fire(int ix)
{
Worker *w = employees.at(ix);
employees.removeAt(ix);
w->employer = nullptr;
num_fired++;
}
// Distribute any excess funds as bonuses/dividends. Excess is defined as
// the current balance (after sales have been taken into account), less
// committed funds (i.e. funds needed to pay current complement of
// employees and the associated deductions) less the proportion designated
// for investment (i.e. reserved for paying any additional employees). Then
// hire new workers if funds permit.
void Firm::epilogue()
{
if (isGovernment())
{
return;
}
/*
if (_state_supported) {
// ***
// State-supported businesses are set up with a full quota of
// employees and do not receive funds from sales so have no need to
// (and cannot) recruit. As funds are supplied by government for
// payment of wages (and expenses) only, bonuses cannot be paid
// either, so there's nothing to do here.
// ***
return;
}
*/
investment = 0;
if (balance > wages_paid)
{
// We must keep in hand at least the amount needed to pay future wages
double available = balance - wages_paid; // now includes deductions
double investible = (available * _domain->getPropInv()) / 100;
double bonus_funds = ((available - investible) * _domain->getDistributionRate()) / 100;
// We distribute the funds as bonuses before hiring new workers to
// ensure they only get distributed to existing workers.
int emps = employees.count();
int bonuses_paid = 0;
if (emps > 0 && bonus_funds > 0)
{
double bonus = bonus_funds / emps;
for (int i = 0 ; i < employees.count() ; i++)
{
employees[i]->credit(bonus, this);
}
//bonuses_paid = _domain->_gov->payBonuses(bonus_funds / emps);
}
// Adjust calculation if not all the bonus funds were used
if (bonuses_paid < bonus_funds)
{
investible += (bonus_funds - bonuses_paid);
}
balance -= bonuses_paid;
if (!(isGovernment() || balance >= 0))
{
Q_ASSERT(isGovernment() || balance >= 0);
}
// How many more employees can we afford?
double std_wage = _domain->getStdWage();
double current_wage_rate = productivity * std_wage; // Note that productivity is initialised to 1.0 in Account
int num_to_hire = static_cast<int> (floor(investible / (current_wage_rate * (1 + _domain->getPreTaxDedns()))));
// Hire new workers
if (num_to_hire > 0)
{
double invested = hireSome(current_wage_rate, num_to_hire);
// ***
// If we are unable to hire all the workers we want we will
// have reserved funds that do not get spent. Even if we can there
// may well be a non-zero residue, although this would normally get
// incoporated into subsequent investments. Where this fails
// because there are no unemployed workers left to recruit, the
// business sector balance will increase without limit and the
// deficit will eventually stabilise at a positive non-zero value.
//
// To avoid this we must dispose of the surplus funds. We can
// either (a) let the money build up until we can declare a
// dividend (how is this specified?), (b) poach employees by
// offering increased wages (inflation), or (c) invest in capital
// equipment (productivity). For the time being we adopt option (c)
// only.
// ***
double excess = investible - invested;
if (excess > 0)
{
// How many did we just hire?
int new_emps = getNumHired();
if (emps > 0 || new_emps > 0)
{
// Purchase capital equipment
// ***
// This operation distributes the excess funds around the
// other firms, which will be equally unable to use them.
// However as this is happening in the epilogue phase they will
// simply remain in their balances until next triggered, at
// which point they will also have to purchase capital
// equipment. The medium-term result will be a general
// inflation.
// ***
Firm *supplier = _domain->selectRandomFirm(this);
// ***
// We must allow for the possibility that there are no firms
// from which to select a supplier. This will be the case if
// parameters were set up with fewer than two startups, and
// selectRandomFirm(this) will then have returned nullptr.
// ***
if (supplier != nullptr)
{
//qDebug() << "crediting" << excess << "to supplier";
supplier->credit(excess, this);
balance -= excess;
investment = excess;
/*
* Update productivity
*/
double n = _domain->getCapexRecoupTime();
/* THIS NEEDS REVIEWING!
* ---------------------
* We to recoup the investment over n periods, so we
* need to raise an additional (excess / n) per period.
* This can be shared out over the new number of
* employees, giving an additional
* excess / (n * (emps+new_emps))
* per employee. The new wage rate will then be
* current_wage_rate + (excess / (n * (emps+new_emps))
* and productivity will be that amount divided by
* std_wage.
*
* I think!
*/
productivity = (current_wage_rate +
(excess / (n * double(double(emps) + new_emps))
)
) / std_wage;
}
}
}
}
}
}
/*
* We no longer keep a separate list of unemployed workers.
*/
Worker *Firm::hire(double wage)
{
foreach (Worker *w, _domain->workers)
{
if (w->employer == nullptr) // unemployed
{
employees.append(w);
w->setAgreedWage(wage); // TODO: should check wage acceptable
w->setEmployer(this);
num_hired += 1;
return w;
}
}
return nullptr;
}
/*
* Review and revise if necessary...
*/
double Firm::hireSome(double wage, int number_to_hire)
{
int count;
double wages_due;
for (count = 0, wages_due = 0; count < number_to_hire; count++)
{
Worker *w = hire(wage);
if (w == nullptr)
{
break;
}
else
{
wages_due += w->agreed_wage;
}
}
// qDebug() << employees.count() << "employees hired";
return wages_due;
}
void Firm::credit(double amount, Account *creditor, bool force)
{
//qDebug() << "Firm::credit (" << amount << ", ...)";
Account::credit(amount);
// If state-supported the reason we are being credited must be that we have
// asked for additional support to pay wages, in which case we have now
// finished (unless direct purchasing, in which case force == true). If we
// are not state-supported (or it's a direct purchase) the credit will be
// for a sale, and sales tax is therefore due.
if (!creditor->isGovernment() || force)
{
sales_receipts += amount;
// Base class credits account but doesn't pay tax. We assume seller,
// not buyer, is responsible for paying sales tax and that payments
// to a Firm are always for purchases and therefore subject to
// sales tax.
int r = _domain->getSalesTaxRate();
if (r > 0)
{
double t = (amount * r) / 100;
qDebug() << "Firm::credit() paying sales tax" << t << "on" << amount;
if (transferSafely(_domain->government(), t, this)) {
sales_tax_paid += t;
}
}
}
}
size_t Firm::getNumEmployees()
{
return 0; // FIX: IMPORTANT
};
double Firm::getProductivity()
{
return productivity;
}
double Firm::getWagesPaid()
{
return wages_paid;
}
double Firm::getInvestment()
{
return investment;
}
double Firm::getBonusesPaid()
{
return bonuses_paid;
}
double Firm::getSalesTaxPaid()
{
return sales_tax_paid;
}
double Firm::getSalesReceipts()
{
return sales_receipts;
}
/*
size_t Firm::getNumEmployees()
{
return static_cast<size_t> (employees.count());
}
*/
int Firm::getNumHired()
{
return num_hired;
}
int Firm::getNumFired()
{
return num_fired;
}