]> git.sur5r.net Git - c128-kasse/blobdiff - src/kasse.c
actually increment transaction id
[c128-kasse] / src / kasse.c
index 06453790ce0ecc0d59ae23509c43e39099d05d34..5c0ddb9389735dc0cb4da17a4c514e65e57e44d9 100644 (file)
@@ -1,8 +1,10 @@
-/*
+/* 
  * RGB2R-C128-Kassenprogramm
- * (c) 2007 phil_fry, sECuRE, sur5r
+ * © 2007-2009 phil_fry, sECuRE, sur5r
+ * See LICENSE for license information
  *
  */
+#define _IS_KASSE
 #include <stdio.h>
 #include <conio.h>
 #include <stdlib.h>
 #include "kasse.h"
 #include "credit_manager.h"
 #include "c128time.h"
+#include "print.h"
 // drucker 4 oder 5
 // graphic 4,0,10
 
-char print_buffer[81];
+static void sane_exit() {
+       save_items();
+       save_credits();
+       exit(1);
+}
 
 /* Hauptbildschirm ausgeben */
 static void print_screen() {
@@ -26,140 +33,207 @@ static void print_screen() {
        char profit[10];
        clrscr();
        if (format_euro(profit, 10, money) == NULL) {
-               cprintf("Einname %ld konnte nicht umgerechnet werden\r\n", money);
+               cprintf("Einnahme %ld konnte nicht umgerechnet werden\r\n", money);
                exit(1);
        }
-       cprintf("C128-Kassenprogramm (phil_fry, sECuRE, sur5r)\r\
-\r\nUhrzeit: %s (wird nicht aktualisiert)\r\
-Eingenommen: %s, Verkauft: %ld Flaschen, Drucken: %s\r\n\r\n", 
+       cprintf("C128-Kassenprogramm (phil_fry, sECuRE, sur5r) " GV "\r\
+\r\nUhrzeit:     %s (wird nicht aktualisiert)\r\
+Eingenommen: %s, Verkauft: %ld Dinge, Drucken: %s\r\n",
        time, profit, items_sold, (printing == 1 ? "ein" : "aus"));
-       for (; i < status.num_items; ++i)
-               cprintf("Eintrag %x: %s (%d Cents, %d mal verkauft)\r\n",
-                       i, status.status[i].item_name, status.status[i].price, status.status[i].times_sold);
-       cprintf("\r\nBefehle: s) Daten sichern d) Drucken umschalten\r\
-g) Guthabenverwaltung     z) Zeit setzen\r\
-n) Neues Getraenk\r\n");
-}
+       cprintf("\xB0\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xB2\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xB2\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xB2\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xAE\r\n");
+       for (; i < min(status.num_items, 15); ++i) {
+               if (format_euro(profit, sizeof(profit), status.status[i].price) == NULL) {
+                       cprintf("Preis %ld konnte nicht umgerechnet werden\r\n", status.status[i].price);
+                       exit(1);
+               }
 
-static void log_file(const char *s) {
-       BYTE c = cbm_open((BYTE)8, (BYTE)8, (BYTE)1, "log");
-       if (c != 0) {
-               c128_perror(c, "cbm_open(log)");
-               save_items();
-               save_credits();
-               exit(1);
-       }
-       c = cbm_write((BYTE)8, s, strlen(s));
-       if (c != strlen(s)) {
-               cprintf("Could not save logfile, please make sure the floppy is not full!\n");
-               save_items();
-               save_credits();
-               exit(1);
+               cprintf("\x7D%2d: %-" xstr(MAX_ITEM_NAME_LENGTH) "s \x7D%s, %3dx \x7D",
+                       i, status.status[i].item_name, profit, status.status[i].times_sold);
+               if ((i+16) < status.num_items) {
+
+                       if (format_euro(profit, sizeof(profit), status.status[i+16].price) == NULL) {
+                               cprintf("Preis %ld konnte nicht umgerechnet werden\r\n", status.status[i+16].price);
+                               exit(1);
+                       }
+                       cprintf("%2d: %-" xstr(MAX_ITEM_NAME_LENGTH) "s \x7D%s, %3dx \x7D",
+                               i+16, status.status[i+16].item_name, profit, status.status[i+16].times_sold);
+               } else cprintf("              \x7D                \x7D");
+               cprintf("\r\n");
        }
-       cbm_close((BYTE)8);
+       cprintf("\xAD\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xB1\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xB1\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xB1\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\x60\xBD\r\n");
+       cprintf(
+"   s) Daten sichern                 d) Drucken umschalten\r\
+   g) Guthabenverwaltung            z) Zeit setzen\r\
+   f) Freitext verkaufen            q) Beenden\r\n");
 }
 
-/* Druckt eine entsprechende Zeile aus */
-static void print_log(BYTE n, int einheiten, char *nickname) {
-       BYTE c;
+/*
+ * Prints a line and logs it to file. Every line can be at max 80 characters.
+ *
+ */
+static void print_log(char *name, int item_price, int einheiten, char *nickname, char *rest) {
        char *time = get_time();
        char price[10];
        /* Format: 
-          Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!)
-          Uhrzeit
-          Eintragname (= Getränk)
-          Preis (in Cents)
-          Anzahl
-          Nickname (falls es vom Guthaben abgezogen wird)
+          Transaction-ID (Anzahl verkaufter Einträge, inklusive des zu druckenden!) -- 6-stellig
+          Uhrzeit -- 8-stellig
+          Eintragname (= Getränk) -- 9-stellig
+          Preis (in Cents) -- 9-stellig
+          Anzahl -- 2-stellig
+          Nickname (falls es vom Guthaben abgezogen wird) -- 10-stellig
+          restguthaben (9-stellig)
+
+          + 7 leerzeichen
+          --> 48 zeichen
           */
-       if (format_euro(price, 10, status.status[n].price) == NULL) {
-               cprintf("Preis %d konnte nicht umgerechnet werden\r\n", status.status[n].price);
-               exit(1);
-       }
-               
-       sprintf(print_buffer, "[%lu] %s - %s - %s - %d - an %s\r\n",
-               items_sold, time, status.status[n].item_name, price, 
-               einheiten, (nickname != NULL ? nickname : "Unbekannt"));
-       c = cbm_open((BYTE)4, (BYTE)4, (BYTE)0, NULL);
-       if (c != 0) {
-               c128_perror(c, "cbm_open(printer)");
-               save_items();
-               save_credits();
+       if (format_euro(price, 10, item_price) == NULL) {
+               cprintf("Preis %d konnte nicht umgerechnet werden\r\n", item_price);
                exit(1);
        }
-       c = cbm_write((BYTE)4, print_buffer, strlen(print_buffer));
-       if (c != strlen(print_buffer)) {
-               c128_perror(c, "write(printer)");
-               save_items();
-               save_credits();
-               exit(1);
-       }
-       cbm_close((BYTE)4);
-       log_file(print_buffer);
+
+       sprintf(print_buffer, "%c[%3u] %s - %-" xstr(MAX_ITEM_NAME_LENGTH) "s - %s - %s - %d - an %s\r",  17,
+                       status.transaction_id, time, name, price, rest,
+                       einheiten, (*nickname != '\0' ? nickname : "Unbekannt"));
+       status.transaction_id++;
+       print_the_buffer();
 }
 
-/* Dialog, der einen durch's Abrechnen der Einträge führt */
-void buy(BYTE n) {
+/* dialog which is called for each bought item */
+static signed int buy(char *name, unsigned int price) {
        int negative = 1;
        char entered[5] = {'1', 0, 0, 0, 0};
        BYTE i = 0, matches = 0;
        BYTE c, nickname_len;
        int einheiten;
-       char *nickname;
+       char *input;
+       char nickname[11];
+       char rest[11];
+       struct credits_t *credit;
 
-       if (status.status[n].item_name == NULL) {
-               cprintf("FEHLER: Diese Einheit existiert nicht.\r\n");
-               return;
-       }
-       cprintf("Wieviel Einheiten \"%s\"? [1] \r\n", status.status[n].item_name);
+       memset(rest, ' ', sizeof(rest));
+       rest[8] = '\0';
+
+       clrscr();
+       cprintf("Wieviel Einheiten \"%s\"? [1] \r\n", name);
        while (1) {
-               c = getchar();
+               c = cgetc();
                if (c == 13)
                        break;
-               else if (c == 27) {
+               cputc(c);
+               if (c == 27) {
                        cprintf("Kauf abgebrochen, druecke RETURN...\r\n");
                        get_input();
-                       return;
+                       return 1;
                } else if (c == '-' && i == 0)
                        negative = -1;
                else if (c > 47 && c < 58)
                        entered[i++] = c;
        }
        einheiten = atoi(entered) * negative;
+       
+       toggle_videomode();
+       cprintf("\r\n             *** VERKAUF ***\r\n\r\n");
+       cprintf("%dx %s", einheiten, name);
+       toggle_videomode();
+       
        cprintf("\r\nAuf ein Guthaben kaufen? Wenn ja, Nickname eingeben:\r\n");
-       nickname = get_input();
-       if (nickname != NULL && *nickname != '\0' && *nickname != 32) {
+       input = get_input();
+       strncpy(nickname, input, 11);
+       if (*nickname != '\0') {
+               toggle_videomode();
+               cprintf(" fuer %s\r\n", nickname);
+               toggle_videomode();
+       }
+
+       if (*nickname != '\0' && *nickname != 32) {
                nickname_len = strlen(nickname);
                /* go through credits and remove the amount of money or set nickname
                 * to NULL if no such credit could be found */
-               for (c = 0; c < credits.num_items; ++c)
-                       if (strncmp(nickname, credits.credits[c].nickname, nickname_len) == 0) {
-                               if (credits.credits[c].credit < (status.status[n].price * einheiten)) {
-                                       cprintf("Sorry, %s hat nicht genug Geld :-(\r\n", nickname);
-                                       return;
-                               }
-                               /* Geld abziehen */
-                               credits.credits[c].credit -= (status.status[n].price * einheiten);
-                               cprintf("\r\nVerbleibendes Guthaben fuer %s: %d Cents. Druecke RETURN...\r\n",
-                                       nickname, credits.credits[c].credit);
+               credit = find_credit(nickname);
+               if (credit != NULL) {
+                       if ((signed int)credit->credit < ((signed int)price * einheiten)) {
+                               cprintf("Sorry, %s hat nicht genug Geld :-(\r\n", nickname);
                                get_input();
-                               matches++;
-                               break;
+                               return 0;
                        }
-               if (matches == 0) {
+                       /* substract money */
+                       credit->credit -= (price * einheiten);
+
+                       if (format_euro(rest, 10, credit->credit) == NULL) {
+                               cprintf("Preis %d konnte nicht umgerechnet werden\r\n", credit->credit);
+                               exit(1);
+                       }
+
+                       cprintf("\r\nVerbleibendes Guthaben fuer %s: %s. Druecke RETURN...\r\n",
+                               nickname, rest);
+                       toggle_videomode();
+                       cprintf("\r\nDein Guthaben betraegt noch %s.\r\n", rest);
+                       toggle_videomode();
+                       get_input();
+                       matches++;
+               } else {
                        cprintf("\r\nNickname nicht gefunden in der Guthabenverwaltung! Abbruch, druecke RETURN...\r\n");
                        get_input();
-                       return;
+                       return 0;
                }
        } else {
                /* Ensure that nickname is NULL if it's empty because it's used in print_log */
-               nickname = NULL;
+               *nickname = '\0';
        }
-       status.status[n].times_sold += einheiten;
-       money += status.status[n].price * einheiten;
+       
+       money += price * einheiten;
        items_sold += einheiten;
        if (printing == 1)
-               print_log(n, einheiten, nickname);
+               print_log(name, price, einheiten, nickname, rest);
+
+       return einheiten;
+}
+
+void buy_stock(BYTE n) {
+       if (n >= status.num_items || status.status[n].item_name == NULL) {
+               cprintf("FEHLER: Diese Einheit existiert nicht.\r\n");
+               get_input();
+               return;
+       }
+
+       status.status[n].times_sold += buy(status.status[n].item_name, status.status[n].price);
+}
+
+void buy_custom() {
+       BYTE c = 0, i = 0;
+       int negative = 1;
+       char entered[5] = {'1', 0, 0, 0, 0};
+       char *input, name[20];
+       int price;
+
+       clrscr();
+       memset(name, '\0', 20);
+       cprintf("\r\nWas soll gekauft werden?\r\n");
+       input = get_input();
+       strncpy(name, input, 20);
+       if (*name == '\0')
+               return;
+
+       cprintf("\r\nWie teuer ist \"%s\" (in cents)?\r\n", name);
+       while (1) {
+               c = cgetc();
+               if (c == 13)
+                       break;
+               cputc(c);
+               if (c == 27) {
+                       cprintf("Kauf abgebrochen, druecke RETURN...\r\n");
+                       get_input();
+                       return;
+               } else if (c == '-' && i == 0)
+                       negative = -1;
+               else if (c > 47 && c < 58)
+                       entered[i++] = c;
+       }
+       price = atoi(entered) * negative;
+
+       cprintf("\r\n");
+
+       buy(name, price);
 }
 
 void set_time_interactive() {
@@ -180,57 +254,76 @@ void set_time_interactive() {
        set_time(tp1, tp2, tp3);
 
        time = get_time();
-       cprintf("Zeit gesetzt: %s\r\n", time);
+       cprintf("\r\nZeit gesetzt: %s\r\n", time);
 }
 
 int main() {
        char *c;
-       toggle_videomode();
-       /* Zeit erstmalig setzen */
+       char *time;
+
+       if (VIDEOMODE == 40)
+               toggle_videomode();
+       clrscr();
+       /* Set time initially, c128 doesn't know it */
        set_time_interactive();
+
        POKE(216, 255);
-       /* Variablen zurechtbiegen */
-       credits.num_items = 0;
-       status.num_items = 0;
-       /* Konfigurationsdatei laden */
+
+       /* Load configuration */
        load_config();
-       /* Einträge (=Getränke) und Zustand laden */
+
+       /* Load items (= drinks) */
        load_items();
-       /* Guthaben laden */
+       /* Load credits */
        load_credits();
+
+       time = get_time();
+       sprintf(print_buffer, "%c--------------------------------------------------------------------------------\r", 17);
+       print_the_buffer();
+       sprintf(print_buffer, "%cC128-Kasse Version " GV "\r", 17);
+       print_the_buffer();
+
+       sprintf(print_buffer, "%cKasse gestartet um %s. Nutze logfile log-%u, zeile %d.\r", 17, time, log_num, log_lines_written);
+       print_the_buffer();
+
+       print_header();
+
        while (1) {
-               /* Bildschirm anzeigen */
                print_screen();
-               /* Tastatureingaben abfragen */
                c = get_input();
-               /* und eventuell weitere Dialoge anzeigen */
-               if (*c > 47 && *c < 58)
-                       buy((*c) - 48);
-               else if (*c == 's') {
-                       /* Zustandsdatei schreiben */
+               /* ...display dialogs eventually */
+               if (*c > 47 && *c < 58) {
+                       /* if the input starts with a digit, we will interpret it as a number
+                        * for the item to be sold */
+                       buy_stock(atoi(c));
+                       toggle_videomode();
+                       clrscr();
+                       toggle_videomode();
+               } else if (*c == 'f') {
+                       buy_custom();
+                       toggle_videomode();
+                       clrscr();
+                       toggle_videomode();
+               } else if (*c == 's') {
                        save_items();
                        save_credits();
                        cprintf("Statefile/Creditfile gesichert, druecke RETURN...\r\n");
                        get_input();
                } else if (*c == 'd') {
-                       /* Drucken an- oder ausschalten */
+                       /* enable/disable printing */
                        printing = (printing == 1 ? 0 : 1);
                        cprintf("Drucken ist nun %s, druecke RETURN...\r\n", 
                                (printing == 1 ? "eingeschaltet" : "ausgeschaltet"));
                        get_input();
                } else if (*c == 'g') {
-                       /* Guthabenverwalter aufrufen */
                        credit_manager();
                } else if (*c == 'z') {
-                       /* Zeit setzen */
                        set_time_interactive();
-               } else if (*c == 'n') {
-                       strcpy(status.status[status.num_items].item_name, "mate");
-                       status.status[status.num_items].price = 23;
-                       status.status[status.num_items].times_sold = 5;
-                       status.num_items++;
                } else if (*c == 'q')
                        break;
        }
-       cprintf("BYEBYE\r\n");
+       clrscr();
+       cprintf("\r\nBYEBYE\r\n");
+
+       return 0;
 }