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:
@@ -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
@@ -5,6 +5,8 @@
|
|||||||
#include "treeitem.h"
|
#include "treeitem.h"
|
||||||
#include "mapplication.h"
|
#include "mapplication.h"
|
||||||
|
|
||||||
|
#include "../src/elementtype.h"
|
||||||
|
|
||||||
#include "widgetcomboboxpopuptable.h"
|
#include "widgetcomboboxpopuptable.h"
|
||||||
|
|
||||||
#include "itemnumberdelegate.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:
|
// 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
|
setLineType("CO", index); // type
|
||||||
break;
|
break;
|
||||||
case 1:
|
case ElementType::Material:
|
||||||
setLineType("MT", index); // type
|
setLineType("MT", index); // type
|
||||||
break;
|
break;
|
||||||
case 2:
|
case ElementType::ManPower:
|
||||||
setLineType("MO", index); // type
|
setLineType("MO", index); // type
|
||||||
break;
|
break;
|
||||||
case 3:
|
case ElementType::Machinery:
|
||||||
setLineType("MQ", index); // type
|
setLineType("MQ", index); // type
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -93,17 +93,20 @@ void formElementList::on_buttonDelete_released()
|
|||||||
dApp->Enterprise().open();
|
dApp->Enterprise().open();
|
||||||
QSqlQuery qry = QSqlQuery(dApp->Enterprise());
|
QSqlQuery qry = QSqlQuery(dApp->Enterprise());
|
||||||
|
|
||||||
/*
|
// Check if it's a composed element (TYPE1 = 0) and delete its composition first
|
||||||
if (index.parent().child(index.row(), 2).data().toInt() == 0)
|
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)))
|
if(!qry.exec(QString("DELETE FROM ELEMENTCOMPOSITION WHERE CODE = '%1';").arg(ID)))
|
||||||
{
|
{
|
||||||
qDebug() << "Error ejecutando el query: " << qry.lastError().text() << "\n";
|
qDebug() << "Error ejecutando el query: " << qry.lastError().text() << "\n";
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
if(!qry.exec(QString("DELETE FROM ELEMENT WHERE CODE = '%1';").arg(ID)))
|
if(!qry.exec(QString("DELETE FROM ELEMENT WHERE CODE = '%1';").arg(ID)))
|
||||||
{
|
{
|
||||||
|
|||||||
+16
-7
@@ -279,9 +279,8 @@ void formProduct::save()
|
|||||||
";";
|
";";
|
||||||
|
|
||||||
ElementComp = "UPDATE ELEMENTCOMPOSITION SET "
|
ElementComp = "UPDATE ELEMENTCOMPOSITION SET "
|
||||||
"CODE = :CODE, ELEMENT_CODE = :ELEMENT_CODE, ELEMENT_AMOUNT = :ELEMENT_AMOUNT, ELEMENT_PRICE := ELEMENT_PRICE "
|
"ELEMENT_AMOUNT = :ELEMENT_AMOUNT "
|
||||||
"WHERE "
|
"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:
|
// 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())
|
switch (qry.value(qry.record().indexOf("TYPE1")).toInt())
|
||||||
{
|
{
|
||||||
case 0:
|
case ElementType::Composed:
|
||||||
setLineType("CO", index); // type
|
setLineType("CO", index); // type
|
||||||
break;
|
break;
|
||||||
case 1:
|
case ElementType::Material:
|
||||||
setLineType("MT", index); // type
|
setLineType("MT", index); // type
|
||||||
break;
|
break;
|
||||||
case 2:
|
case ElementType::ManPower:
|
||||||
setLineType("MO", index); // type
|
setLineType("MO", index); // type
|
||||||
break;
|
break;
|
||||||
case 3:
|
case ElementType::Machinery:
|
||||||
setLineType("MQ", index); // type
|
setLineType("MQ", index); // type
|
||||||
break;
|
break;
|
||||||
|
case ElementType::Subcontracted:
|
||||||
|
setLineType("SC", index); // type
|
||||||
|
break;
|
||||||
|
case ElementType::Other:
|
||||||
|
setLineType("OT", index); // type
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
setLineType("UNKNOWN", index); // type
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include "formbase.h"
|
#include "formbase.h"
|
||||||
|
#include "../src/elementtype.h"
|
||||||
|
|
||||||
namespace Ui
|
namespace Ui
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ void ItemNumberDelegate::setEditorData(QWidget *editor, const QModelIndex &index
|
|||||||
{
|
{
|
||||||
QString val = index.model()->data(index, Qt::EditRole).toString();
|
QString val = index.model()->data(index, Qt::EditRole).toString();
|
||||||
val.replace(QString(","), QString("."));
|
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);
|
static_cast<QDoubleSpinBox*>(editor)->setValue(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -63,7 +63,7 @@
|
|||||||
//#include "QsfMainWindow.h"
|
//#include "QsfMainWindow.h"
|
||||||
#include "QMainWindow"
|
#include "QMainWindow"
|
||||||
#include "QTabWidget"
|
#include "QTabWidget"
|
||||||
#include "QMessageBox";
|
#include "QMessageBox"
|
||||||
|
|
||||||
|
|
||||||
#if !SARIBBON_USE_3RDPARTY_FRAMELESSHELPER
|
#if !SARIBBON_USE_3RDPARTY_FRAMELESSHELPER
|
||||||
|
|||||||
@@ -55,7 +55,6 @@
|
|||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QModelIndex>
|
#include <QModelIndex>
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#include "gui/SARibbon/src/SARibbonBar/SARibbonMainWindow.h"
|
#include "gui/SARibbon/src/SARibbonBar/SARibbonMainWindow.h"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user