]> git.pond.sub.org Git - empserver/commitdiff
(coll, fina, repa, shark, disloan): Fix calculation of regular and
authorMarkus Armbruster <armbru@pond.sub.org>
Fri, 20 Aug 2004 07:01:26 +0000 (07:01 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Fri, 20 Aug 2004 07:01:26 +0000 (07:01 +0000)
extended (beyond due date) loan time.  At the due date, or after a
last payment made at the due date, durations were zero in fina() and
unpredictable elsewhere.  With luck, debtors could abuse this to repay
loans cheap (they couldn't gain cash, though), sharks to purchase
loans cheap, and creditors to collect excessively.

src/lib/commands/coll.c
src/lib/commands/fina.c
src/lib/commands/repa.c
src/lib/commands/shark.c
src/lib/subs/disloan.c

index c744e240d1f709eebbe5a02e0b8d6c3baef15b73..941b2d513eb8514a05c175947d77f8adaa5383f6 100644 (file)
@@ -57,8 +57,6 @@ coll(void)
     struct lonstr loan;
     struct sctstr sect;
     coord x, y;
-    long due;
-    long last;
     long rdur;
     long xdur;
     double rate;
@@ -82,19 +80,21 @@ coll(void)
     /* If we got here, we check to see if it's been defaulted on.  We
        already know it's owed to this player. */
     (void)time(&now);
-    due = loan.l_duedate;
-    if (now <= due) {
+    /*
+     * split duration now - l_lastpay into regular (up to l_duedate)
+     * and extended (beyond l_duedate)
+     */
+    rdur = loan.l_duedate - loan.l_lastpay;
+    xdur = now - loan.l_duedate;
+    if (rdur < 0) {
+       xdur += rdur;
+       rdur = 0;
+    }
+    if (xdur <= 0) {
        pr("There has been no default on loan %d\n", arg);
        return RET_FAIL;
     }
-    last = loan.l_lastpay;
-    if (last < due && due < now) {
-       rdur = due - last;
-       xdur = now - due;
-    } else if (due < last) {
-       rdur = 0;
-       xdur = now - last;
-    }
+
     rate = loan.l_irate / (loan.l_ldur * 8.64e6);
 
 /* changed following to avoid overflow 3/27/89 bailey@math-cs.kent.edu
index 93aaf01fee7fda79743962da3798ac3c6ae45f41..b80cce07a4331b462552ff8914a980b884c1a84a 100644 (file)
@@ -56,8 +56,6 @@ fina(void)
     int xdur;
     double rate;
     double amt;
-    time_t due;
-    time_t last;
 
     if (!opt_LOANS) {
        pr("Loans are not enabled.\n");
@@ -73,26 +71,19 @@ fina(void)
     while (nxtitem(&ni, (s_char *)&loan)) {
        if (loan.l_status != LS_SIGNED)
            continue;
-       due = loan.l_duedate;
-       last = loan.l_lastpay;
-       rdur = 0;
-       xdur = 0;
-       if (now < due) {
-           rdur = now - last;
-           xdur = 0;
-       }
-       if (last < due && due < now) {
-           rdur = due - last;
-           xdur = now - due;
-       }
-       if (due < last) {
+       /*
+        * split duration now - l_lastpay into regular (up to l_duedate)
+        * and extended (beyond l_duedate)
+        */
+       rdur = loan.l_duedate - loan.l_lastpay;
+       xdur = now - loan.l_duedate;
+       if (rdur < 0) {
+           xdur += rdur;
            rdur = 0;
-           xdur = now - last;
        }
-       if (loan.l_ldur == 0) {
-           logerror("loan #%d has zero duration", ni.cur);
+
+       if (CANT_HAPPEN(loan.l_ldur == 0))
            continue;
-       }
        rate = loan.l_irate / (loan.l_ldur * 8640000.0);
 
 /* changed following to avoid overflow 3/27/89 bailey@math-cs.kent.edu
index 24dfa3421962d661c378eb2c8fa97d6a6b549fce..c22a96b1c26395b756023f9f0593aab2c550e765 100644 (file)
@@ -50,8 +50,6 @@ repa(void)
     int loan_num;
     long payment;
     long owe;
-    long due;
-    long last_payment;
     long normaltime;
     long doubletime;
     double rate_per_sec, amt;
@@ -76,20 +74,17 @@ repa(void)
        return RET_FAIL;
     }
     (void)time(&now);
-    due = loan.l_duedate;
-    last_payment = loan.l_lastpay;
-    if (now < due) {
-       normaltime = now - last_payment;
-       doubletime = 0;
-    }
-    if (last_payment < due && due < now) {
-       normaltime = due - last_payment;
-       doubletime = now - due;
-    }
-    if (due < last_payment) {
+    /*
+     * split duration now - l_lastpay into regular (up to l_duedate)
+     * and extended (beyond l_duedate)
+     */
+    normaltime = loan.l_duedate - loan.l_lastpay;
+    doubletime = now - loan.l_duedate;
+    if (normaltime < 0) {
+       doubletime += normaltime;
        normaltime = 0;
-       doubletime = now - last_payment;
     }
+
     rate_per_sec = loan.l_irate /
        ((double)loan.l_ldur * SECS_PER_DAY * 100.0);
 
index b9827a8fd807175c6bbc3030358877c82072b68a..9f0adf22277694bd70090e3ed3ee52f59c731a3f 100644 (file)
@@ -55,8 +55,6 @@ shark(void)
     struct lonstr loan;
     struct natstr *natp;
     struct natstr *oldie;
-    long due;
-    long last;
     long rdur;
     long xdur;
     double rate;
@@ -85,19 +83,21 @@ shark(void)
     }
     /* If we got here, we check to see if it's been defaulted on. */
     (void)time(&now);
-    due = loan.l_duedate;
-    if (now <= due) {
+    /*
+     * split duration now - l_lastpay into regular (up to l_duedate)
+     * and extended (beyond l_duedate)
+     */
+    rdur = loan.l_duedate - loan.l_lastpay;
+    xdur = now - loan.l_duedate;
+    if (rdur < 0) {
+       xdur += rdur;
+       rdur = 0;
+    }
+    if (xdur <= 0) {
        pr("There has been no default on loan %d\n", arg);
        return RET_FAIL;
     }
-    last = loan.l_lastpay;
-    if (last < due && due < now) {
-       rdur = due - last;
-       xdur = now - due;
-    } else if (due < last) {
-       rdur = 0;
-       xdur = now - last;
-    }
+
     rate = loan.l_irate / (loan.l_ldur * 8.64e6);
 
     owed = ((rdur * rate) + (xdur * rate * 2.0) + 1.0);
index a0b95482873ffd940de97a97af85c5fae72501d4..625de08c5bcc04c5887baa15807ff9826b9b584b 100644 (file)
@@ -54,8 +54,6 @@ int
 disloan(int n, register struct lonstr *loan)
 {
     time_t now;
-    time_t due;
-    time_t lastpaydate;
     time_t normaltime;
     time_t doubletime;
     time_t accept;
@@ -85,20 +83,18 @@ disloan(int n, register struct lonstr *loan)
        pr("Loan must be accepted by %s", ctime(&accept));
        return 1;
     }
-    due = loan->l_duedate;
-    lastpaydate = loan->l_lastpay;
-    if (now < due) {
-       normaltime = now - lastpaydate;
-       doubletime = 0;
-    }
-    if (lastpaydate < due && due < now) {
-       normaltime = due - lastpaydate;
-       doubletime = now - due;
-    }
-    if (due < lastpaydate) {
+
+    /*
+     * split duration now - l_lastpay into regular (up to l_duedate)
+     * and extended (beyond l_duedate)
+     */
+    normaltime = loan->l_duedate - loan->l_lastpay;
+    doubletime = now - loan->l_duedate;
+    if (normaltime < 0) {
+       doubletime += normaltime;
        normaltime = 0;
-       doubletime = now - lastpaydate;
     }
+
     rate = ((double)loan->l_irate / 100.0) / (loan->l_ldur * SECS_PER_DAY);
     owe = ((double)loan->l_amtdue *
           (((double)normaltime * rate + 1.0) +
@@ -107,7 +103,7 @@ disloan(int n, register struct lonstr *loan)
     pr("Amount due (if paid now) $%.2f", owe);
     if (doubletime == 0) {
        pr(" (if paid on due date) $%.2f\n",
-          loan->l_amtdue * ((due - lastpaydate) * rate + 1.0));
+          loan->l_amtdue * ((loan->l_duedate - loan->l_lastpay) * rate + 1.0));
        pr("Due date is %s", ctime(&loan->l_duedate));
     } else
        pr(" ** In Arrears **\n");