Files

368 lines
13 KiB
C++

#include <QDebug>
#include "fiebdc.h"
//#include "globalvars.h" // Asumiendo que globalVars está definido aquí
#include <QDate>
FIEBDC::FIEBDC(QString filename, Budget* budget) {
__budget = budget;
__filename = filename;
if (__budget != nullptr) {
__budget->filename = __filename;
}
__cancel = false;
__format_list = {"FIEBDC-3/95", "FIEBDC-3/98", "FIEBDC-3/2002",
"FIEBDC-3/2004", "FIEBDC-3/2007"};
__character_sets_dict = {{"ANSI", "cp1252"},
{"850", "850"},
{"437", "cp437"}};
__file_format = "FIEBDC-3/2007";
//__generator = globalVars.name + " " + globalVars.version;
__character_set = "850";
initializePatterns();
}
void FIEBDC::initializePatterns() {
__pattern = {
{"control_tilde", QRegularExpression(R"(((\r\n)| |\t)+~)")},
{"control_vbar", QRegularExpression(R"(((\r\n)| |\t)+\|)")},
{"control_backslash", QRegularExpression(R"(((\r\n)| |\t)+\\)")},
{"valid_code", QRegularExpression(R"([^A-Za-z0-9ñÑ.$#%&_])")},
{"special_char", QRegularExpression(R"([#%&])")},
{"no_float", QRegularExpression(R"([^\-0-9.])")},
{"formula", QRegularExpression(R"(.*[^0123456789\.()\+\-\*/\^abcdp ].*)")},
{"comment", QRegularExpression(R"(#.*\r\n)")},
{"empty_line", QRegularExpression(R"((\r\n) *\r\n)")},
{"space_before_backslash", QRegularExpression(R"(( )+\\)")},
{"space_after_backslash", QRegularExpression(R"(\\( )+)")},
{"start_noend_backslash", QRegularExpression(R"((\r\n\\\.*[^\\\])\r\n)")},
{"end_oper", QRegularExpression(R"((\+|-|\*|/|/^|@|&|<|>|<=|>=|=|!) *\r\n)")},
{"matricial_var", QRegularExpression(R"((\r\n *[%|\$][A-ZÑ].*=.*, ) *\r\n)")},
{"descomposition", QRegularExpression(R"(^([^:]+):(.*)$)")},
{"var", QRegularExpression(R"(^([$%][A-ZÑ][()0-9, ]*)=(.*)$)")},
{"after_first_tilde", QRegularExpression(R"(^[^~]*~)")},
{"end_control", QRegularExpression(R"(((\r\n)| |\t)+$)")}
};
}
void FIEBDC::cancel() {
__cancel = true;
}
QString FIEBDC::eraseControlCharacters(const QString& input) {
// Implementación de la función para eliminar caracteres de control
QString string = input;
string = string.replace(__pattern["control_tilde"], "~");
string = string.replace(__pattern["control_vbar"], "|");
// Uncomment if control_backslash processing is needed
// string = string.replace(__pattern["control_backslash"], "\\");
return string;
}
bool FIEBDC::validateCode(const QString& code) {
// Implementación de la función para validar el código
QRegularExpression re("^[A-Z0-9]+$");
return re.match(code).hasMatch();
}
QDate FIEBDC::parseDate(const QString& dateStr) {
/*parseDate(date)
date: in the format:
uneven len: add a Leading 0
len = 8 DDMMYYYY
len <= 6 DDMMYY “80/20”. >80 -> >1980 <80 -> <2080
len < 5 MMYY
len < 3 YY
Test date string and return a tuple (YYYY, MM, DD)
or None if the date format is invalid
*/
if (dateStr.isEmpty()) {
return QDate();
}
QString paddedDate = dateStr;
if (dateStr.length() % 2 != 0) {
paddedDate.prepend("0"); // Agregar un 0 inicial si la longitud es impar
}
// Intentar con diferentes formatos según la longitud
if (paddedDate.length() == 8) {
return QDate::fromString(paddedDate, "ddMMyyyy");
} else if (paddedDate.length() == 6) {
QString yearPrefix = paddedDate.right(2).toInt() < 80 ? "20" : "19";
return QDate::fromString(yearPrefix + paddedDate, "yyyyMMdd");
} else if (paddedDate.length() == 4) {
QString yearPrefix = paddedDate.right(2).toInt() < 80 ? "20" : "19";
return QDate::fromString(yearPrefix + paddedDate, "yyyyMM");
} else if (paddedDate.length() == 2) {
QString yearPrefix = paddedDate.toInt() < 80 ? "20" : "19";
return QDate::fromString(yearPrefix + paddedDate, "yyyy");
}
return QDate(); // Fecha inválida
}
void FIEBDC::parseRecord(const QString& record) {
/*
parseRecord(record, interface)
record: the record line readed from the file whith the format:
type|field|field|subfield\\subfield|...
[a] nothing or "a"
{a} zero or more #-#twice#-# "a"
<a> one or more #-#twice#-# "a"
Types: V C D Y M N T K L Q J G E X B F A
V: Property and Version
1- [File_Owner]
2- Format_Version[\\DDMMYYYY]
3- [Program_Generator]
4- [Header]\\{Title\\}
5- [Chaters_set]
6- [Comment]
C: Record:
1- Code{\\Code}
2- [Unit]
3- [Summary]
4- {Price\\}
5- {Date\\}
6- [Type]
D or Y: DECOMPOSITION or ADD DECOMPOSITION
1- Parent Code
2- <Child Code\\ [Factor]\\ [Yield]>
M or N: MEASURE or ADD MEASURE
1- [Parent Code\\]Child Code
2- {Path\}
3- TOTAL MEASURE
4- {Type\\Comment\\Unit\\Length\\Width\\Height\\}
5- [Label]
T: Text
1- Code
2- Description text
K: Coefficients
1- { DN \\ DD \\ DS \\ DR \\ DI \\ DP \\ DC \\ DM \\ DIVISA \\ }
2- CI \\ GG \\ BI \\ BAJA \\ IVA
3- { DRC \\ DC \\ DRO \\ DFS \\ DRS \\ DFO \\ DUO \\ DI \\ DES \\ DN \\
DD \\ DS \\ DIVISA \\ }
4- [ n ]
L: Sheet of Conditions 1
A)
1- Empty
2- {Section Code\\Section Title}
B)
1- Record Code
2- {Section Code\\Section Text}
3- {Section Code\\RTF file}
4- {Section Code\\HTM file}
Q: Sheet of Conditions 2
1- Record Code
2- {Section Code\\Paragraph key\\{Field key;}\\}|
J: Sheet of Conditions 3
1- Paragraph code
2- [Paragraph text]
3- [RTF file]
4- [HTML file]
G: Grafic info
1- <grafic_file.ext\\>
E: Company
1- company Code
2 [ summary ]
3- [ name ]
4- { [ type ] \\ [ subname ] \\ [ address ] \\ [ postal_code ]
\\ [ town ] \\ [ province ] \\ [ country ] \\ { phone; }
\\ { fax; } \\ {contact_person; } \\ }
5- [ cif ] \\ [ web ] \\ [ email ] \\
X: Tecnical information
A)
1- Empty
2- < TI_Code \\ TI_Descitption \\ TI_Unit >
B)
1- Record_code
2- < TI_Code \\ TI_value >
F: #-#Adjunto#-# File
1- Record code
2- { Type \\ { Filenames; } \\ [Description] }
B: Change code
1- Record Code
2- New code
A: Labels
1- Record Code
2- <Label\\>
interface:
*/
QStringList fields = record.split("|");
if (fields.isEmpty()) {
return;
}
QString recordType = fields.at(0);
if (recordType == "V")
{
}
else if (recordType == "C")
{
}
else if (recordType == "D" || recordType == "Y")
{
}
else if (recordType == "T")
{
} else {
qDebug() << "Unknown record type:" << recordType << fields;
}
}
void FIEBDC::parseV(QStringList fields)
{
/*
parseV(field_list)
field_list: field list of the record
0- V :Property and Version
1- [File_Owner]
2- Format_Version[\DDMMYYYY]
3- [Program_Generator]
4- [Header]\{Title\}
5- [Chaters_set]
6- [Comment]
7- [Data type]
8- [Number budget certificate]
9- [Date budget certificate]
*/
if (fields.size() < 10) {
qWarning() << "Invalid 'V' record, insufficient fields:" << fields;
return;
}
QString owner = fields[1].trimmed();
QString versionDate = fields[2].trimmed();
QString generator = fields[3].trimmed();
QString headerTitle = fields[4].trimmed();
QString characterSet = fields[5].trimmed();
QString comment = fields[6].trimmed();
QString dataType = fields[7].trimmed();
QString numberCertificate = fields[8].trimmed();
QString dateCertificate = fields[9].trimmed();
// Process version and date
QStringList versionDateParts = versionDate.split("\\");
if (!versionDateParts.isEmpty()) {
auto fileFormat = versionDateParts[0];
qDebug() << "File format set to:" << fileFormat;
if (versionDateParts.size() > 1) {
QDate parsedDate = parseDate(versionDateParts[1]);
if (parsedDate.isValid()) {
qDebug() << "Parsed version date:" << parsedDate;
}
}
}
/*
# _____number of fields_____
# Any INFORMATION after last field separator is ignored
if len(field_list) > 10:
field_list = field_list[:10]
# If there are no sufficient fields, the fields are added
# with empty value:""
else:
field_list = field_list + [""]*(10-len(field_list))
# control character are erased: end of line, tab, space
# only leading and trailing whitespace in owner, generator, comment
# _____Fields_____
_record_type = self.delete_control_space(field_list[0])
_owner = field_list[1].strip()
_owner = self.delete_control(_owner)
_version_date = self.delete_control_space(field_list[2])
_generator = field_list[3].strip()
_generator = self.delete_control(_generator)
_header_title = field_list[4].strip()
_header_title = self.delete_control(_header_title)
_character_set = self.delete_control_space(field_list[5])
_comment = field_list[6].strip("\t \n\r")
_data_type = self.delete_control_space(field_list[7])
_number_certificate = self.delete_control_space(field_list[8])
__date_certificate = self.delete_control_space(field_list[9])
# _____Owner_____
self.__budget.setOwner(_owner)
# _____Version-Date_____
_version_date = _version_date.split("\\")
_file_format = _version_date[0]
if _file_format in self.__format_list:
self.__file_format = _file_format
_tuni = _("FIEBDC format: $1")
_uni = utils.mapping(_tuni, (_file_format,))
print(_uni)
if len(_version_date) > 1:
_date = _version_date[1]
if _date != "":
_parsed_date = self.parseDate(_date)
if _parsed_date is not None:
self.__budget.setDate(_parsed_date)
# _____Generator_____
# ignored field
_tuni = _("FIEBDC file generated by $1")
_uni = utils.mapping(_tuni, (_generator,))
print(_uni)
# _____Header_Title_____
_header_title = _header_title.split("\\")
_header_title = [_title.strip() for _title in _header_title]
_header = _header_title.pop(0)
_title = [ ]
for _title_index in _header_title:
if _title_index != "":
_title.append(_title_index)
if _header != "":
self.__budget.setTitleList([ _header, _title])
# _____Characters_set_____
# field parsed in readFile method
# _____Comment_____
if _comment != "":
self.__budget.setComment(_comment)
# _____Data type_____
# 1 -> Base data.
# 2 -> Budget.
# 3 -> Budget certificate.
# 4 -> Base date update.
try:
_data_type = int(_data_type)
except ValueError:
_data_type = ""
if _data_type == 3:
# _____Number budget certificate_____
try:
_number_certificate = int(_number_certificate)
except ValueError:
_number_certificate = ""
# _____Date budget certificate_____
if _date_certificate != "":
_parsed_date_certificate = self.parseDate(_date_certificate)
if _parsed_date_certificate is None:
_date_certificate = ""
else:
_date_certificate = _parsed_date_certificate
self.__budget.setBudgetype(_data_type)
self.__budget.setCertificateOrder(_number_certificate)
self.__budget.setCertificateDate(_parsed_date_cerfificate)
elif _data_type != "":
self.__budget.setBudgeType(_data_type)
self.__statistics.valid = self.__statistics.valid + 1
*/
}
void FIEBDC::readFile(Budget* budget, QString filename) {
// Implementación de la función para leer el archivo
if (budget != nullptr) {
__budget = budget;
}
if (!filename.isEmpty()) {
__filename = filename;
}
// Lógica para leer el archivo
}