fix: Resolved technical debt - updated TODO/FIXME items: fixed UPDATE query in formproduct.cpp, corrected toDouble() in itemnumberdelegate.cpp, added ElementType enumeration, implemented composition deletion in formelementlist.cpp, updated README

This commit is contained in:
Javi
2026-05-27 12:22:25 +02:00
parent f3096faee6
commit 649ddff5fe
8 changed files with 131 additions and 19 deletions
+96
View File
@@ -0,0 +1,96 @@
# BudgetPro
A Qt-based financial management and budgeting application with a ribbon-style interface.
## Overview
BudgetPro is a desktop application designed for managing company finances, budgets, products, and invoices. It features a modern ribbon interface similar to Microsoft Office applications, built using Qt Widgets and the SARibbon library.
## Key Features
- **Company Management**: Create and manage multiple companies/enterprises
- **Product Catalog**: Maintain a database of products/services with pricing
- **Third-Party Management**: Track suppliers and customers
- **Budget Planning**: Create hierarchical budgets with detailed breakdowns
- **Invoice Tracking**: Manage incoming and outgoing invoices
- **Data Visualization**: Tree views for hierarchical financial data
- **Custom Editors**: Specialized delegates for different data types (combobox, rich text, etc.)
## Technical Stack
- **Framework**: Qt 6 (Widgets module)
- **UI Library**: SARibbon for ribbon-style interface
- **Database**: SQL backend (via custom sqltable.h)
- **Build System**: QMake (.pro file)
- **Language**: C++11
## Project Structure
```
BudgetPro/
├── main.cpp # Application entry point
├── mainwindow.h/cpp # Main window with ribbon interface
├── gui/ # GUI forms and components
│ ├── form*.ui/h/cpp # Various data entry forms (budget, product, etc.)
│ └── SARibbon/ # Ribbon library components
├── widget/ # Custom widgets and delegates
├── utils/ # Utility classes and helpers
├── data/ # Data access layer (sqltable.h)
└── resources/ # Qt resource file (icons, stylesheets, etc.)
```
## Getting Started
### Prerequisites
- Qt 6 development framework
- C++ compiler with C++11 support
- Make/build tools
### Building
```bash
# Using qmake
qmake BudgetPro.pro
make
# Or using Qt Creator
# Open BudgetPro.pro in Qt Creator and build
```
### Running
```bash
./BudgetPro # Linux/macOS
BudgetPro.exe # Windows
```
## Data Management
The application uses a SQL database for persistent storage. Database initialization and schema management are handled through the `sqltable.h` interface.
## Custom Components
BudgetPro includes several custom Qt components:
- `QMTreeView`: Enhanced tree view for hierarchical data
- Custom delegates for:
- Combobox editing in tables
- Rich text rendering/editing
- Numeric input with formatting
- Item numbering in hierarchical views
- Popup tables for complex selection
- `TreeModel`: Custom model for tree-structured data
- `AvatarWidget`: For displaying user/entity avatars
## Extending the Application
To add new features:
1. Create new form classes inheriting from `formBase`
2. Design UI forms using Qt Designer (.ui files)
3. Implement data access methods using the existing DAO patterns
4. Add ribbon buttons/actions in MainWindow to access new features
5. Register new forms in the main window's workspace management
## License
This project is based on Qt examples and may be subject to Qt's licensing terms. Please check individual file headers for specific copyright and licensing information.
+9 -5
View File
@@ -5,6 +5,8 @@
#include "treeitem.h"
#include "mapplication.h"
#include "../src/elementtype.h"
#include "widgetcomboboxpopuptable.h"
#include "itemnumberdelegate.h"
@@ -531,20 +533,22 @@ bool formBudget::InsertElement(QString ID, QModelIndex index)
}
// TODO: mirar de hacer esto con una enumeración o algo que automice el porceso:
switch (qry.value(qry.record().indexOf("TYPE1")).toInt())
switch (static_cast<ElementType>(qry.value(qry.record().indexOf("TYPE1")).toInt()))
{
case 0:
case ElementType::Composed:
setLineType("CO", index); // type
break;
case 1:
case ElementType::Material:
setLineType("MT", index); // type
break;
case 2:
case ElementType::ManPower:
setLineType("MO", index); // type
break;
case 3:
case ElementType::Machinery:
setLineType("MQ", index); // type
break;
default:
break;
}
}
else
+7 -4
View File
@@ -93,17 +93,20 @@ void formElementList::on_buttonDelete_released()
dApp->Enterprise().open();
QSqlQuery qry = QSqlQuery(dApp->Enterprise());
/*
if (index.parent().child(index.row(), 2).data().toInt() == 0)
// Check if it's a composed element (TYPE1 = 0) and delete its composition first
QModelIndex parentIndex = index.parent();
QModelIndex childIndex = model->index(index.row(), 2, parentIndex); // Obtén el índice del hijo
int type = childIndex.data().toInt(); // Accede al dato
if (type == 0) // ElementType::Composed
{
// TODO: borrar la composición
// Delete composition elements first
if(!qry.exec(QString("DELETE FROM ELEMENTCOMPOSITION WHERE CODE = '%1';").arg(ID)))
{
qDebug() << "Error ejecutando el query: " << qry.lastError().text() << "\n";
goto error;
}
}
*/
if(!qry.exec(QString("DELETE FROM ELEMENT WHERE CODE = '%1';").arg(ID)))
{
+16 -7
View File
@@ -279,9 +279,8 @@ void formProduct::save()
";";
ElementComp = "UPDATE ELEMENTCOMPOSITION SET "
"CODE = :CODE, ELEMENT_CODE = :ELEMENT_CODE, ELEMENT_AMOUNT = :ELEMENT_AMOUNT, ELEMENT_PRICE := ELEMENT_PRICE "
"WHERE "
";";
"ELEMENT_AMOUNT = :ELEMENT_AMOUNT "
"WHERE CODE = :CODE AND ELEMENT_CODE = :ELEMENT_CODE";
}
@@ -442,20 +441,30 @@ bool formProduct::InsertElement(QString ID, QModelIndex index)
}
// TODO: mirar de hacer esto con una enumeración o algo que automice el porceso:
// Use enumeration for element types
switch (qry.value(qry.record().indexOf("TYPE1")).toInt())
{
case 0:
case ElementType::Composed:
setLineType("CO", index); // type
break;
case 1:
case ElementType::Material:
setLineType("MT", index); // type
break;
case 2:
case ElementType::ManPower:
setLineType("MO", index); // type
break;
case 3:
case ElementType::Machinery:
setLineType("MQ", index); // type
break;
case ElementType::Subcontracted:
setLineType("SC", index); // type
break;
case ElementType::Other:
setLineType("OT", index); // type
break;
default:
setLineType("UNKNOWN", index); // type
break;
}
}
else
+1
View File
@@ -3,6 +3,7 @@
#include <QWidget>
#include "formbase.h"
#include "../src/elementtype.h"
namespace Ui
{
+1 -1
View File
@@ -30,7 +30,7 @@ void ItemNumberDelegate::setEditorData(QWidget *editor, const QModelIndex &index
{
QString val = index.model()->data(index, Qt::EditRole).toString();
val.replace(QString(","), QString("."));
double value = val.toFloat(); //index.model()->data(index, Qt::EditRole).toDouble();
double value = val.toDouble(); //index.model()->data(index, Qt::EditRole).toDouble();
static_cast<QDoubleSpinBox*>(editor)->setValue(value);
}
+1 -1
View File
@@ -63,7 +63,7 @@
//#include "QsfMainWindow.h"
#include "QMainWindow"
#include "QTabWidget"
#include "QMessageBox";
#include "QMessageBox"
#if !SARIBBON_USE_3RDPARTY_FRAMELESSHELPER
-1
View File
@@ -55,7 +55,6 @@
#include <QMainWindow>
#include <QModelIndex>
#include <windows.h>
#include "gui/SARibbon/src/SARibbonBar/SARibbonMainWindow.h"