7 Commits
Author SHA1 Message Date
admin fa0e377811 Aggiunti commenti doxygen a include 2026-10-11 13:45:37 +02:00
rexeref defa951e51 pulito file tree 2026-10-10 20:41:45 +02:00
rexeref c088caf03e rimosso .fpm dal tree 2026-10-10 20:40:49 +02:00
rexeref 8cd79da5eb Aggiunta gestione export csv 2026-10-10 20:40:24 +02:00
rexeref 8b5b690435 pulizia da file superflui 2026-10-10 19:19:00 +02:00
rexeref c6543cc583 Modifiche e correzioni generali ai assisted 2026-10-10 19:18:28 +02:00
rexeref 05237cc7f1 Update README.md 2026-10-09 17:33:58 +02:00
13 changed files with 2097 additions and 246 deletions

No files matched your search

+4 -3
View File
@@ -3,9 +3,10 @@ Un gestore di inventario e vendite minimale
## Scaricarlo
Disponibile solo per linux.
Scarica l'ultima versione da [qui](https://git.lug.uniroma2.it/rexeref/productManager/releases)!
Scarica l'ultima versione dalla pagina delle releases!
Avvia l'eseguibile da un terminale.
Se non si avvia rendilo prima un eseguibile con chmod +x
***questo codice molto probabilmente NON è sicuro, utilizzarlo a propria indiscrezione***
## Troubleshooting
wip
+1
View File
@@ -7,5 +7,6 @@
extern char productPricesFileLocation[64]; // Dichiarazione extern
extern char countFileLocation[64];
extern char configFileLocation[64];
#endif
+68
View File
@@ -0,0 +1,68 @@
#ifndef JSONFILE_H
#define JSONFILE_H
#include <json-c/json.h>
/**
* @brief Verifica se un file esiste sul disco.
* @param fname Percorso del file da controllare.
* @return 1 se il file esiste ed è accessibile, 0 altrimenti.
*/
int existsFile(const char *fname);
/**
* @brief Crea un nuovo file JSON inizializzandolo con un array vuoto ([]).
* @param fname Percorso del file da creare.
* @return 0 in caso di successo, -1 in caso di errore.
*/
int createFile(const char *fname);
/**
* @brief Rinomina o sposta un file esistente.
* @param oldName Vecchio percorso/nome del file.
* @param newName Nuovo percorso/nome del file.
* @return 0 in caso di successo, -1 in caso di errore.
*/
int renameDataFile(const char *oldName, const char *newName);
/**
* @brief Carica un array JSON da file. Se il file non esiste, lo crea automaticamente.
* @param fname Percorso del file JSON.
* @return Puntatore all'oggetto JSON (array) caricato, oppure NULL in caso di errore.
*/
json_object *loadJsonArray(const char *fname);
/**
* @brief Salva un array JSON su file formattandolo in modo leggibile (indentato).
* @param fname Percorso del file di destinazione.
* @param arr L'oggetto JSON (array) da salvare.
* @return 0 in caso di successo, -1 in caso di errore.
*/
int saveJsonArray(const char *fname, json_object *arr);
/**
* @brief Cerca un oggetto all'interno di un array JSON basandosi sul campo "name".
* @param arr L'array JSON in cui effettuare la ricerca.
* @param name La stringa del nome da cercare.
* @return Puntatore all'oggetto JSON trovato, oppure NULL se non esiste.
*/
json_object *findItemByName(json_object *arr, const char *name);
/**
* @brief Rimuove un oggetto da un array JSON basandosi sul campo "name".
* @param arr L'array JSON da cui rimuovere l'elemento.
* @param name Il nome dell'elemento da eliminare.
* @return 0 in caso di successo, 1 se l'elemento non viene trovato, -1 in caso di errore.
*/
int removeItemByName(json_object *arr, const char *name);
/**
* @brief Modifica il campo "name" di un elemento all'interno di un array JSON.
* @param arr L'array JSON contenente l'elemento.
* @param oldName Il nome attuale dell'elemento da rinominare.
* @param newName Il nuovo nome da assegnare.
* @return 0 in caso di successo, 1 se l'elemento non viene trovato, -1 in caso di errore.
*/
int renameItemByName(json_object *arr, const char *oldName, const char *newName);
#endif
+201 -7
View File
@@ -1,12 +1,13 @@
#ifndef LOGIC_H
#define LOGIC_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ncurses.h>
#include <json-c/json.h>
#include "jsonFile.h"
#define PRODUCT_STOCK_UNLIMITED (-1)
struct product {
float cost;
@@ -14,23 +15,216 @@ struct product {
char name;
};
/* File */
int existsFile(const char *fname);
int createFile(const char *fname);
int renameDataFile(const char *oldName, const char *newName);
/* ------------------------------------------------------------------ */
/* Prodotti */
/* ------------------------------------------------------------------ */
/**
* @brief Restituisce l'array JSON contenente tutti i prodotti.
* @param fname Percorso del file JSON dei prodotti.
* @return Puntatore all'oggetto JSON (array) dei prodotti (da liberare con json_object_put()), oppure NULL in caso di errore.
*/
json_object *getProducts(const char *fname);
/**
* @brief Stampa a schermo (tramite ncurses) la lista dei prodotti con relativo prezzo, inventario e tag bundle.
* @param fname Percorso del file JSON dei prodotti.
*/
void listProducts(const char *fname);
/**
* @brief Aggiunge un nuovo prodotto con prezzo e inventario illimitato.
* @param fname Percorso del file JSON dei prodotti.
* @param name Nome del prodotto.
* @param price Prezzo del prodotto.
* @return 0 in caso di successo, 1 se il prodotto esiste già, -1 in caso di errore.
*/
int addProduct(const char *fname, const char *name, double price);
/**
* @brief Aggiunge un nuovo prodotto specificando prezzo e quantità iniziale in magazzino.
* @param fname Percorso del file JSON dei prodotti.
* @param name Nome del prodotto.
* @param price Prezzo del prodotto.
* @param stock Quantità iniziale in magazzino (-1 per inventario illimitato).
* @return 0 in caso di successo, 1 se il prodotto esiste già, -1 in caso di errore.
*/
int addProductWithInventory(const char *fname, const char *name, double price, int stock);
/**
* @brief Aggiunge un prodotto composto (bundle) costituito da altri componenti.
* @param fname Percorso del file JSON dei prodotti.
* @param name Nome del bundle.
* @param price Prezzo del bundle.
* @param components Oggetto JSON (array) descrivente i componenti e le relative quantità.
* @return 0 in caso di successo, 1 se il prodotto esiste già, -1 in caso di errore.
*/
int addBundleProduct(const char *fname, const char *name, double price, json_object *components);
/**
* @brief Ottiene il prezzo di un prodotto specifico.
* @param fname Percorso del file JSON dei prodotti.
* @param name Nome del prodotto da cercare.
* @return Il prezzo del prodotto, oppure -1.0 se non trovato o in caso di errore.
*/
double getPrice(const char *fname, const char *name);
/**
* @brief Aggiorna nome e prezzo di un prodotto esistente, sincronizzando anche le vendite se il nome cambia.
* @param productsFile Percorso del file JSON dei prodotti.
* @param soldFile Percorso del file JSON delle vendite.
* @param oldName Nome attuale del prodotto.
* @param newName Nuovo nome da assegnare al prodotto.
* @param price Nuovo prezzo del prodotto.
* @return 0 in caso di successo, codice di errore/stato altrimenti.
*/
int updateProduct(const char *productsFile, const char *soldFile, const char *oldName, const char *newName, double price);
/**
* @brief Aggiorna nome, prezzo e inventario di un prodotto esistente.
* @param productsFile Percorso del file JSON dei prodotti.
* @param soldFile Percorso del file JSON delle vendite.
* @param oldName Nome attuale del prodotto.
* @param newName Nuovo nome da assegnare.
* @param price Nuovo prezzo.
* @param stock Quantità in magazzino.
* @return 0 in caso di successo, codice di errore/stato altrimenti.
*/
int updateProductWithInventory(const char *productsFile, const char *soldFile, const char *oldName, const char *newName, double price, int stock);
/**
* @brief Legge lo stato dell'inventario (quantità e tracciamento) di un prodotto.
* @param fname Percorso del file JSON dei prodotti.
* @param name Nome del prodotto.
* @param stock Puntatore a intero in cui salvare la quantità di magazzino.
* @param tracked Puntatore a intero in cui salvare se l'inventario è tracciato (1) o meno (0).
* @return 0 in caso di successo, 1 se il prodotto non viene trovato, -1 in caso di errore.
*/
int getProductInventory(const char *fname, const char *name, int *stock, int *tracked);
/**
* @brief Imposta la quantità e lo stato di tracciamento dell'inventario per un prodotto.
* @param fname Percorso del file JSON dei prodotti.
* @param name Nome del prodotto.
* @param stock Quantità di magazzino da impostare.
* @param tracked Flag di tracciamento (1 per tracciato, 0 altrimenti).
* @return 0 in caso di successo, 1 se il prodotto non è trovato, -1 in caso di errore.
*/
int setProductInventory(const char *fname, const char *name, int stock, int tracked);
/**
* @brief Consuma (scala) una determinata quantità dall'inventario di un prodotto o dei suoi componenti (se bundle).
* @param fname Percorso del file JSON dei prodotti.
* @param name Nome del prodotto.
* @param qty Quantità da consumare.
* @return 0 in caso di successo, codice di errore o disponibilità insufficiente altrimenti.
*/
int consumeProductInventory(const char *fname, const char *name, int qty);
/* ------------------------------------------------------------------ */
/* Copie vendute */
/* ------------------------------------------------------------------ */
/**
* @brief Restituisce il numero di copie vendute di un determinato prodotto.
* @param fname Percorso del file JSON delle vendite.
* @param name Nome del prodotto.
* @return Il numero di copie vendute (0 se non presente, -1 in caso di errore).
*/
int getCount(const char *fname, const char *name);
/**
* @brief Stampa a schermo (tramite ncurses) la lista delle vendite registrate per ciascun prodotto.
* @param fname Percorso del file JSON delle vendite.
*/
void listSold(const char *fname);
/**
* @brief Aggiunge una quantità di copie vendute per un prodotto (creando la voce se non esiste).
* @param fname Percorso del file JSON delle vendite.
* @param name Nome del prodotto.
* @param qty Quantità venduta da aggiungere.
* @return 0 in caso di successo, -1 in caso di errore.
*/
int addSold(const char *fname, const char *name, int qty);
/**
* @brief Elimina la registrazione delle vendite di un prodotto e ripristina l'inventario corrispondente.
* @param productsFile Percorso del file JSON dei prodotti.
* @param soldFile Percorso del file JSON delle vendite.
* @param name Nome del prodotto di cui eliminare le vendite.
* @return 0 in caso di successo, 1 se la vendita non è presente, -1 o codice di errore in caso di fallimento.
*/
int deleteSold(const char *productsFile, const char *soldFile, const char *name);
/**
* @brief Aggiorna la quantità di copie vendute per un prodotto, regolando di conseguenza il magazzino.
* @param productsFile Percorso del file JSON dei prodotti.
* @param soldFile Percorso del file JSON delle vendite.
* @param name Nome del prodotto.
* @param qty Nuova quantità totale venduta.
* @return 0 in caso di successo, 1 se non presente, codice di errore altrimenti.
*/
int updateSold(const char *productsFile, const char *soldFile, const char *name, int qty);
/**
* @brief Registra una vendita scalando l'inventario dei prodotti e incrementando le vendite, con supporto di rollback in caso di problemi.
* @param productsFile Percorso del file JSON dei prodotti.
* @param soldFile Percorso del file JSON delle vendite.
* @param name Nome del prodotto venduto.
* @param qty Quantità venduta.
* @return 0 in caso di successo, codice di errore in caso di fallimento.
*/
int recordSale(const char *productsFile, const char *soldFile, const char *name, int qty);
/* ------------------------------------------------------------------ */
/* Entrate */
/* ------------------------------------------------------------------ */
/**
* @brief Calcola le entrate totali sommando il prodotto tra prezzo e copie vendute per ciascun articolo.
* @param productsFile Percorso del file JSON dei prodotti.
* @param soldFile Percorso del file JSON delle vendite.
* @return Il totale delle entrate, oppure -1.0 in caso di errore.
*/
double getTotalRevenue(const char *productsFile, const char *soldFile);
/* ------------------------------------------------------------------ */
/* Export */
/* ------------------------------------------------------------------ */
/**
* @brief Esporta i dati delle vendite e dei prodotti in un file in formato CSV.
* @param productsFile Percorso del file JSON dei prodotti.
* @param soldFile Percorso del file JSON delle vendite.
* @param outFile Percorso del file CSV di output.
* @return 0 in caso di successo, un valore negativo in caso di errore.
*/
int exportSalesToCsv(const char *productsFile, const char *soldFile, const char *outFile);
/* ------------------------------------------------------------------ */
/* Config */
/* ------------------------------------------------------------------ */
/**
* @brief Assicura che il file di configurazione dell'applicazione esista, creandolo se necessario.
* @param fname Percorso del file di configurazione.
* @return 0 in caso di successo, codice di errore altrimenti.
*/
int ensureAppConfig(const char *fname);
/**
* @brief Carica la configurazione dell'applicazione dal file specificato.
* @param fname Percorso del file di configurazione.
* @return 0 in caso di successo, -1 in caso di errore.
*/
int loadAppConfig(const char *fname);
/**
* @brief Salva la configurazione corrente dell'applicazione sul file specificato.
* @param fname Percorso del file di configurazione.
* @return 0 in caso di successo, -1 in caso di errore.
*/
int saveAppConfig(const char *fname);
#endif
+77
View File
@@ -6,18 +6,95 @@
#include <string.h>
#include <ncurses.h>
/**
* @brief Crea e restituisce una nuova finestra ncurses con i bordi tracciati.
* @param height Altezza della finestra.
* @param width Larghezza della finestra.
* @param starty Coordinata Y iniziale sullo schermo.
* @param startx Coordinata X iniziale sullo schermo.
* @return Puntatore all'oggetto WINDOW creato.
*/
WINDOW *create_newwin(int height, int width, int starty, int startx);
/**
* @brief Distrugge una finestra ncurses creata in precedenza e libera la memoria associata.
* @param local_win Puntatore alla finestra da eliminare.
*/
void destroy_win(WINDOW *local_win);
/**
* @brief Stampa del testo all'interno di una finestra gestendo l'andata a capo automatica (word wrapping) per parola.
* @param win Finestra in cui stampare.
* @param start_y Coordinata Y iniziale all'interno della finestra.
* @param start_x Coordinata X iniziale all'interno della finestra.
* @param str Stringa di testo da stampare.
*/
void wwrap_print(WINDOW *win, int start_y, int start_x, const char *str);
/**
* @brief Gestisce un interruttore grafico interattivo (stato ON/OFF) modificabile da tastiera.
* @param win Finestra di visualizzazione.
* @param y Coordinata Y dell'interruttore.
* @param x Coordinata X dell'interruttore.
* @param state Stato iniziale (1 per ON, 0 per OFF).
* @return Lo stato finale dell'interruttore dopo l'interazione dell'utente.
*/
int uiToggleSwitch(WINDOW *win, int y, int x, int state);
/**
* @brief Gestisce un campo di input di testo interattivo all'interno di una finestra ncurses.
* @param win Finestra in cui inserire il testo.
* @param y Coordinata Y.
* @param x Coordinata X.
* @param input Buffer contenente l'eventuale testo iniziale e in cui memorizzare il risultato digitato.
* @param max_len Lunghezza massima consentita per l'input.
*/
void uiTextInput(WINDOW *win, int y, int x, char *input, int max_len);
/**
* @brief Mostra un menu di scelta multipla navigabile da tastiera tramite frecce o tasti vim (j/k).
* @param win Finestra in cui mostrare il menu.
* @param start_y Coordinata Y iniziale.
* @param start_x Coordinata X iniziale.
* @param options Array di stringhe contenente le opzioni del menu.
* @param n_options Numero totale di opzioni disponibili.
* @return L'indice (1-based) della voce selezionata dall'utente.
*/
int uiSelectMenu(WINDOW *win, int start_y, int start_x, char **options, int n_options);
/**
* @brief Stampa un menu all'interno di una finestra evidenziando una voce specifica.
* @param menu_win Finestra del menu.
* @param y Coordinata Y.
* @param x Coordinata X.
* @param highlight Indice della voce da evidenziare graficamente.
*/
void print_menu(WINDOW *menu_win, int y, int x, int highlight);
/**
* @brief Mostra una finestra di avviso (warning) utilizzando una stringa formattata (stile printf).
* @param fmt Stringa di formattazione.
* @param ... Argomenti variabili da formattare.
*/
void warningf(const char *fmt, ...);
/**
* @brief Apre una finestra di popup con un messaggio di avviso e attende la pressione di un tasto per chiudersi.
* @param string Messaggio di errore o avviso da mostrare.
*/
void warning(char *string);
/**
* @brief Aggiorna la barra di stato in basso sullo schermo con un messaggio formattato (stile printf).
* @param fmt Stringa di formattazione.
* @param ... Argomenti variabili da formattare.
*/
void statusf(const char *fmt, ...);
/**
* @brief Scrive un messaggio direttamente nella barra di stato in basso sullo schermo.
* @param msg Messaggio da visualizzare nella status bar.
*/
void status(char *msg);
#endif
+2
View File
@@ -9,10 +9,12 @@
int runMainMenu();
void runOptionsMenu();
void runSellWindow();
void runCreateBundleWindow();
void runAboutWindow();
void runViewSalesWindow();
void runViewProductsWindow();
void runAddProductWindow();
void runExportCsvWindow();
void example_window();
#endif
+1 -1
View File
@@ -36,6 +36,6 @@ bundle: $(OBJECTS)
@rm -fr dist/
clean:
rm -rf $(BUILD_DIR) $(EXEC) dist *.json
rm -rf $(BUILD_DIR) $(EXEC) dist *.json .fpm
.PHONY: all clean bundle
+1
View File
@@ -2,4 +2,5 @@
char productPricesFileLocation[64]="./pm-item-price-default.json";
char countFileLocation[64]="./pm-item-sold-count-default.json";
char configFileLocation[64]=".fpm";
+113
View File
@@ -0,0 +1,113 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <json-c/json.h>
#include "../include/jsonFile.h"
int existsFile(const char *fname) {
FILE *file = fopen(fname, "r");
if (file) {
fclose(file);
return 1;
}
return 0;
}
int createFile(const char *fname) {
json_object *arr = json_object_new_array();
if (!arr)
return -1;
int res = json_object_to_file_ext(fname, arr, JSON_C_TO_STRING_PRETTY);
json_object_put(arr);
return (res == 0) ? 0 : -1;
}
int renameDataFile(const char *oldName, const char *newName) {
return (rename(oldName, newName) == 0) ? 0 : -1;
}
static json_object *loadRawArray(const char *fname) {
if (!existsFile(fname) && createFile(fname) != 0)
return NULL;
FILE *f = fopen(fname, "r");
if (!f)
return NULL;
int empty = (fgetc(f) == EOF);
fclose(f);
if (empty)
return json_object_new_array();
json_object *arr = json_object_from_file(fname);
if (!arr)
return NULL;
if (!json_object_is_type(arr, json_type_array)) {
json_object_put(arr);
return NULL;
}
return arr;
}
json_object *loadJsonArray(const char *fname) {
return loadRawArray(fname);
}
int saveJsonArray(const char *fname, json_object *arr) {
if (!arr)
return -1;
return (json_object_to_file_ext(fname, arr, JSON_C_TO_STRING_PRETTY) == 0) ? 0 : -1;
}
json_object *findItemByName(json_object *arr, const char *name) {
if (!arr || !name)
return NULL;
size_t n = json_object_array_length(arr);
for (size_t i = 0; i < n; i++) {
json_object *item = json_object_array_get_idx(arr, i);
json_object *jname = NULL;
if (json_object_object_get_ex(item, "name", &jname) &&
strcmp(json_object_get_string(jname), name) == 0)
return item;
}
return NULL;
}
int removeItemByName(json_object *arr, const char *name) {
if (!arr || !name)
return -1;
size_t n = json_object_array_length(arr);
for (size_t i = 0; i < n; i++) {
json_object *item = json_object_array_get_idx(arr, i);
json_object *jname = NULL;
if (json_object_object_get_ex(item, "name", &jname) &&
strcmp(json_object_get_string(jname), name) == 0) {
json_object_array_del_idx(arr, (int)i, 1);
return 0;
}
}
return 1;
}
int renameItemByName(json_object *arr, const char *oldName, const char *newName) {
if (!arr || !oldName || !newName)
return -1;
json_object *item = findItemByName(arr, oldName);
if (!item)
return 1;
json_object_object_add(item, "name", json_object_new_string(newName));
return 0;
}
+805 -97
View File
File diff suppressed because it is too large. Load diff
+4 -24
View File
@@ -22,6 +22,7 @@
#include "../include/windowsDeclaration.h"
#include "../include/windowsBack.h"
#include "../include/logic.h"
#include "../include/globals.h"
void printLogoBG();
@@ -43,36 +44,15 @@ int main(){
noecho();
curs_set(0);
raw();
if (loadAppConfig(configFileLocation) != 0)
warningf("Impossibile caricare la config '%s', uso i valori di default.", configFileLocation);
printLogoBG();
statusf(" ");
refresh();
int running = 0;
while(running != 6){
while (runMainMenu()) {
printLogoBG();
refresh();
running = runMainMenu();
switch(running) {
case 1:
runSellWindow();
break;
case 2:
runViewSalesWindow();
break;
case 3:
runViewProductsWindow();
break;
case 4:
runAddProductWindow();
break;
case 5:
runAboutWindow();
// runOptionsMenu();
break;
case 6:
break;
}
}
endwin();
+1
View File
@@ -1,6 +1,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <ncurses.h>
#include "../include/windowsBack.h"
+819 -114
View File
File diff suppressed because it is too large. Load diff