void SubcategoryEditor::addNewChild() { //launch dialog to ask for the new child. Using this same dialog. SubcategoryEditor *scEditor = new SubcategoryEditor(this); scEditor->setDb(db); Azahar *myDb = new Azahar; myDb->setDatabase(db); scEditor->setCatList( catList ); scEditor->setScatList( scatList ); scEditor->setDialogType(dialogType+1);//incrementing because this dialog is a child dialog (parentType+1) if (dialogType == 1) { //From "Add Department" dialog, creating a category. scEditor->setLabelForName(i18n("New category:")); scEditor->setLabelForList(i18n("Select the child subcategories for this category:")); scEditor->populateList( myDb->getSubCategoriesList() ); } else if (dialogType == 2) { //From "Add Category" dialog, creating a subcategory. No child allowed. scEditor->setLabelForName(i18n("New subcategory:")); scEditor->setLabelForList(i18n("")); scEditor->hideListView(); //subcategories does not have children. } if ( scEditor->exec() ) { QString text = scEditor->getName(); QStringList children = scEditor->getChildren(); qDebug()<<text<<" CHILDREN:"<<children; if (dialogType == 1) { //The dialog is launched from the "Add Department" dialog. So we are going to create a category. //Create the category if (!myDb->insertCategory(text)) { qDebug()<<"Error:"<<myDb->lastError(); delete myDb; return; } //insert new category to the box catList << text; ui->listView->addItem(text); //mark item as checkable ui->listView->item(ui->listView->count()-1)->setFlags(ui->listView->item(ui->listView->count()-1)->flags() |Qt::ItemIsUserCheckable); ui->listView->item(ui->listView->count()-1)->setCheckState(Qt::Checked); //mark as checked. qulonglong cId = myDb->getCategoryId(text); //create the m2m relations for the new category->subcategory. foreach(QString cat, children) { //get subcategory id qulonglong scId = myDb->getSubCategoryId(cat); //create the link [category] --> [subcategory] myDb->insertM2MCategorySubcategory(cId, scId); } } else if (dialogType == 2) { //The dialog is launched from the "Add Category" dialog. So we are going to create a subcategory which does have a child.
void PurchaseEditor::checkIfCodeExists() { Azahar *myDb = new Azahar; myDb->setDatabase(db); gelem = ""; QString codeStr = ui->editCode->text(); if (codeStr.isEmpty()) codeStr = "0"; ProductInfo pInfo = myDb->getProductInfo(codeStr); if (pInfo.code ==0 && pInfo.desc=="Ninguno") productExists = false; if (pInfo.code > 0) { status = estatusMod; productExists = true; qtyOnDb = pInfo.stockqty; //Prepopulate dialog... ui->editDesc->setText(pInfo.desc); setCategory(pInfo.category); setMeasure(pInfo.units); ui->editCost->setText(QString::number(pInfo.cost)); ui->editTax->setText(QString::number(pInfo.tax)); //FIXME: add tax models //ui->editExtraTaxes->setText(QString::number(pInfo.extratax)); ui->editFinalPrice->setText(QString::number(pInfo.price)); ui->editPoints->setText(QString::number(pInfo.points)); ui->chIsAGroup->setChecked(pInfo.isAGroup); gelem = pInfo.groupElementsStr; if (!(pInfo.photo).isEmpty()) { QPixmap photo; photo.loadFromData(pInfo.photo); setPhoto(photo); } } else { qDebug()<< "no product found with code "<<codeStr; qulonglong codeSaved = getCode(); resetEdits(); setCode(codeSaved); } }
void SpecialOrderEditor::addItem() { double dqty = 1; //if not any value, default is ONE QStringList msgP; QStringList msgU; int incTime = 0; Azahar *myDb = new Azahar; myDb->setDatabase(db); if (!ui->editAddQty->text().isEmpty()) { dqty = ui->editAddQty->text().toDouble(); } //get selected items from source view QItemSelectionModel *selectionModel = ui->sourcePView->selectionModel(); QModelIndexList indexList = selectionModel->selectedRows(); // pasar el indice que quiera (0=code, 1=name) foreach(QModelIndex index, indexList) { qulonglong code = index.data().toULongLong(); QString codeStr = index.data().toString(); bool exists = false; ProductInfo pInfo; //get product info from hash or db if (groupInfo.productsList.contains(code)) { pInfo = groupInfo.productsList.take(code); //check measures for the product if (pInfo.units == 1 ) { //by pieces QString tmpStr = ui->editAddQty->text(); if (tmpStr.endsWith(".00")) tmpStr.chop(3); //discard .00's if (tmpStr.endsWith(".0")) tmpStr.chop(2);//discard .00's if (tmpStr.contains(".") || tmpStr.contains(",")) { int tmp = dqty; dqty = tmp; //pass to integer instead of double msgP.append(i18n("<i>%1</i> rounded to %2",pInfo.desc,tmp)); incTime += 1000; } } if (pInfo.stockqty >= pInfo.qtyOnList+dqty) pInfo.qtyOnList += dqty; //increment it else { incTime += 1000; msgU.append(i18n("<i>%1</i> <b>requested %2, on stock %3</b><br>", pInfo.desc,dqty,pInfo.stockqty)); } //if not enough, its not incremented. exists = true; } else { pInfo = myDb->getProductInfo(codeStr); //check measures for the product if (pInfo.units == 1) { //by pieces QString tmpStr = ui->editAddQty->text(); if (tmpStr.endsWith(".00")) tmpStr.chop(3);//discard .00's if (tmpStr.endsWith(".0")) tmpStr.chop(2);//discard .00's if (tmpStr.contains(".") || tmpStr.contains(",")) { int tmp = dqty; dqty = tmp; //pass to integer instead of double msgP.append(i18n("<i>%1</i> rounded to %2",pInfo.desc,tmp)); incTime += 1000; } } pInfo.qtyOnList = 0; if (pInfo.stockqty >= dqty) pInfo.qtyOnList = dqty; else { incTime += 1000; msgU.append(i18n("<i>%1</i> <b>requested %2, on stock %3</b><br>", pInfo.desc,dqty,pInfo.stockqty)); } } // Insert/Update GroupView if (!exists) { //check if it is available. if (pInfo.qtyOnList <= 0 ) { //NO, its not available. continue; qDebug()<<"Continue..."; } // Insert into the groupView int rowCount = ui->groupView->rowCount(); ui->groupView->insertRow(rowCount); ui->groupView->setItem(rowCount, 0, new QTableWidgetItem(QString::number(dqty))); ui->groupView->setItem(rowCount, 1, new QTableWidgetItem(pInfo.desc)); } else { if (pInfo.qtyOnList <= 0 ) { //NO, its not available. continue; qDebug()<<"Continue..."; } //simply update the groupView with the new qty for (int ri=0; ri<ui->groupView->rowCount(); ++ri) { QTableWidgetItem * item = ui->groupView->item(ri, 1); QString name = item->data(Qt::DisplayRole).toString(); if (name == pInfo.desc) { //update QTableWidgetItem *itemQ = ui->groupView->item(ri, 0);//item qty itemQ->setData(Qt::EditRole, QVariant(pInfo.qtyOnList)); continue; } } } // update info of the group groupInfo.count = groupInfo.count+dqty; groupInfo.cost += pInfo.cost*dqty; //pInfo.qtyOnList; groupInfo.price += pInfo.price*dqty; //pInfo.qtyOnList; //NOTE:group price is not affected by any product discount, it takes normal price. // Discounts are taken into consideration after adding to the purchase list, when calculating taxes and price for the SO. bool yes = false; if (pInfo.stockqty >= dqty ) yes = true; groupInfo.isAvailable = (groupInfo.isAvailable && yes ); // Insert product to the group hash groupInfo.productsList.insert(code, pInfo); if (!yes) { //Just warning!... the insert into the view is above... qDebug()<<"Product is not available!"; } }
void PurchaseEditor::insertProduct(ProductInfo info) { //When a product is already on list, increment qty. bool existed = false; if (info.code>0) { if (productsHash.contains(info.code)) { info = productsHash.take(info.code); //re get it from hash info.purchaseQty += getPurchaseQty(); itemCount += getPurchaseQty(); totalBuy = totalBuy + info.cost*getPurchaseQty(); existed = true; } else { itemCount += info.purchaseQty; totalBuy = totalBuy + info.cost*info.purchaseQty; } //calculate taxes for this item. Calculated from the costs. Azahar *myDb = new Azahar; myDb->setDatabase(db); double cWOTax = 0; if (myDb->getConfigTaxIsIncludedInPrice()) cWOTax= (info.cost)/(1+((info.tax+info.extratax)/100)); else cWOTax = info.cost; double tax = cWOTax*info.purchaseQty*(info.tax/100); double tax2= cWOTax*info.purchaseQty*(info.extratax/100); totalTaxes += tax + tax2; // add this product taxes to the total taxes in the purchase. qDebug()<<"Total taxes updated:"<<totalTaxes<<" Taxes for this product:"<<tax+tax2; delete myDb; double finalCount = info.purchaseQty + info.stockqty; info.groupElementsStr=""; //grouped products cannot be a group. //insert item to productsHash productsHash.insert(info.code, info); //insert item to ListView if (!existed) { int rowCount = ui->tableView->rowCount(); ui->tableView->insertRow(rowCount); ui->tableView->setItem(rowCount, 0, new QTableWidgetItem(QString::number(info.code))); ui->tableView->setItem(rowCount, 1, new QTableWidgetItem(info.desc)); ui->tableView->setItem(rowCount, 2, new QTableWidgetItem(QString::number(info.purchaseQty))); ui->tableView->setItem(rowCount, 3, new QTableWidgetItem(QString::number(finalCount))); } else { //simply update the groupView with the new qty for (int ri=0; ri<ui->tableView->rowCount(); ++ri) { QTableWidgetItem * item = ui->tableView->item(ri, 1); QString name = item->data(Qt::DisplayRole).toString(); if (name == info.desc) { //update QTableWidgetItem *itemQ = ui->tableView->item(ri, 2); itemQ->setData(Qt::EditRole, QVariant(QString::number(info.purchaseQty))); itemQ = ui->tableView->item(ri, 3); itemQ->setData(Qt::EditRole, QVariant(QString::number(finalCount))); continue; //HEY PURIST, WHEN I GOT SOME TIME I WILL CLEAN IT } } } ui->tableView->horizontalHeader()->setResizeMode(QHeaderView::Interactive); ui->tableView->resizeRowsToContents(); //totalBuy = totalBuy + info.cost*info.purchaseQty; //itemCount = itemCount + info.purchaseQty; //update info on group caption ui->groupBox->setTitle( i18n("Items in this purchase [ %1 items, %2 ]",itemCount, KGlobal::locale()->formatMoney(totalBuy, QString(), 2) ) ); qDebug()<<"totalBuy until now:"<<totalBuy<<" itemCount:"<<itemCount<<"info.cost:"<<info.cost<<"info.purchaseQty:"<<info.purchaseQty; } else qDebug()<<"Item "<<info.code<<" already on hash"; }
void PurchaseEditor::calculatePrice() { double finalPrice=0.0; bool costOk,profitOk,taxOk,etaxOk; if (ui->editCost->text().isEmpty() && !ui->groupBoxedItem->isChecked() ) { ui->editCost->setText("0.0"); //ui->editCost->setFocus(); ui->editCost->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); costOk = false; } else { ui->editCost->setStyleSheet(""); costOk=true; } if (ui->editUtility->text().isEmpty()) { //ui->editUtility->setFocus(); ui->editUtility->setText("0.0"); ui->editUtility->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); profitOk=false; } else { ui->editUtility->setStyleSheet(""); profitOk=true; } if (ui->editTax->text().isEmpty()) { ui->editTax->setText("0.0"); //ui->editTax->setFocus(); ui->editTax->selectAll(); ui->editTax->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); taxOk=false; } else { ui->editTax->setStyleSheet(""); taxOk=true; } if (ui->editExtraTaxes->text().isEmpty()) { ui->editExtraTaxes->setText("0.0"); //ui->editExtraTaxes->setFocus(); ui->editExtraTaxes->selectAll(); ui->editExtraTaxes->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); etaxOk = false; } else { etaxOk = true; ui->editExtraTaxes->setStyleSheet(""); } //now check which are ZEROs // if (!ui->editExtraTaxes->text().isEmpty() && ui->editExtraTaxes->text().toDouble()<=0) // ui->editExtraTaxes->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); // else ui->editExtraTaxes->setStyleSheet(""); if (!ui->editTax->text().isEmpty() && ui->editTax->text().toDouble()<=0) ui->editTax->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); else ui->editTax->setStyleSheet(""); if (!ui->editUtility->text().isEmpty() && ui->editUtility->text().toDouble()<=0) ui->editUtility->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); else ui->editUtility->setStyleSheet(""); if (!ui->editCost->text().isEmpty() && ui->editCost->text().toDouble()<=0) ui->editCost->setStyleSheet("background-color: rgb(255,100,0); color:white; selection-color: white; font-weight:bold;"); else ui->editCost->setStyleSheet(""); if (costOk && profitOk && taxOk && etaxOk ) { //TODO: if TAXes are included in cost... double cWOTax = 0; double tax = ui->editTax->text().toDouble(); double tax2 = ui->editExtraTaxes->text().toDouble(); double utility = ui->editUtility->text().toDouble(); Azahar *myDb = new Azahar; myDb->setDatabase(db); // We assume that tax rules for prices also apply to costs. if (myDb->getConfigTaxIsIncludedInPrice()) cWOTax= (ui->editCost->text().toDouble())/(1+((tax+tax2)/100)); else cWOTax = ui->editCost->text().toDouble(); double cost = cWOTax; utility = ((utility/100)*cost); double cu=cost+utility; //We need the tax recalculated from the costs+utility, this time taxes are expressed in $ tax = ((tax/100)*(cost)); ///NOTE fixed:when paying for a product we pay taxes for the cost not the cost+profit tax2 = ((tax2/100)*(cost)); if (ui->groupBoxedItem->isChecked()){ double itemsPerBox = 0; double pricePerBox = 0; if (!ui->editItemsPerBox->text().isEmpty()) itemsPerBox = ui->editItemsPerBox->text().toDouble(); if (!ui->editPricePerBox->text().isEmpty()) pricePerBox = ui->editPricePerBox->text().toDouble(); if (!ui->editItemsPerBox->text().isEmpty() || !ui->editPricePerBox->text().isEmpty()) return; tax = ui->editTax->text().toDouble(); tax2 = ui->editExtraTaxes->text().toDouble(); if (myDb->getConfigTaxIsIncludedInPrice()) cWOTax= (pricePerBox/itemsPerBox)/(1+((tax+tax2)/100)); else cWOTax = pricePerBox/itemsPerBox; cost = cWOTax; ui->editCost->setText(QString::number(cost)); utility = ((ui->editUtility->text().toDouble()/100)*cost); cu = cost + utility; tax = ((tax/100)*(cost));///NOTE fixed:when paying for a product we pay taxes for the cost not the cost+profit tax2 = ((tax2/100)*(cost)); finalPrice = cu + tax + tax2; } else finalPrice = cost + utility + tax + tax2; qDebug()<<"cWOTax ="<<cWOTax<<" tax1="<<tax<<" tax2="<<tax2<<" FinalPrice:"<<finalPrice; ui->editFinalPrice->setText(QString::number(finalPrice)); ui->editFinalPrice->selectAll(); delete myDb; } }
void PromoEditor::populateCategoriesCombo() { Azahar *myDb = new Azahar; myDb->setDatabase(db); ui->comboCategory->addItems(myDb->getCategoriesList()); }
void PurchaseEditor::addItemToList() { ProductInfo pInfo; Azahar *myDb = new Azahar; myDb->setDatabase(db); bool ok=false; if (ui->editCode->text().isEmpty()) ui->editCode->setFocus(); else if (ui->editDesc->text().isEmpty()) ui->editDesc->setFocus(); else if (ui->editPoints->text().isEmpty()) ui->editPoints->setFocus(); else if (ui->editCost->text().isEmpty()) ui->editCost->setFocus(); else if (ui->editTax->text().isEmpty()) ui->editTax->setFocus(); else if (ui->editFinalPrice->text().isEmpty()) ui->editFinalPrice->setFocus(); else if (ui->editQty->text().isEmpty() || ui->editQty->text()=="0") ui->editQty->setFocus(); else if ((ui->editUtility->text().isEmpty() && ui->editFinalPrice->text().isEmpty()) || ui->editFinalPrice->text().toDouble()<=ui->editCost->text().toDouble() ) ui->editFinalPrice->setFocus(); else if (ui->groupBoxedItem->isChecked() && (ui->editItemsPerBox->text().isEmpty() || ui->editItemsPerBox->text()=="0")) ui->editItemsPerBox->setFocus(); else if (ui->groupBoxedItem->isChecked() && (ui->editPricePerBox->text().isEmpty() || ui->editPricePerBox->text()=="0")) ui->editPricePerBox->setFocus(); else ok = true; if (ok) { ProductInfo info = myDb->getProductInfo(QString::number(getCode())); if (info.code == 0) { info.code = getCode(); info.lastProviderId=1; //for now.. fixme in the future } //update p.info from the dialog info.desc = getDescription(); info.price = getPrice(); info.cost = getCost(); info.tax = getTax1(); //FIXME: add tax models //info.extratax= getTax2(); info.photo = getPhotoBA(); info.units = getMeasureId(); info.category= getCategoryId(); info.profit = getProfit(); info.points = getPoints(); info.stockqty= getQtyOnDb(); info.purchaseQty = getPurchaseQty(); double finalCount = info.purchaseQty + info.stockqty; // WHAT FOR?? info.validDiscount = productExists; //used to check if product is already on db. //FIXME: NEXT 2 lines are temporal remove on 0.8 version //info.alphaCode = "-NA-"; //FIXME: last providerId for an existent must be gotten from db since we dont have that field here. Provide a combobox to select one and a button to add a new one. //info.lastProviderId = 1; if (info.isAGroup) { // get each product fo the group/pack QStringList list = gelem.split(","); for (int i=0; i<list.count(); ++i) { QStringList tmp = list.at(i).split("/"); if (tmp.count() == 2) { //ok 2 fields qulonglong code = tmp.at(0).toULongLong(); pInfo = myDb->getProductInfo(QString::number(code)); pInfo.purchaseQty = getPurchaseQty(); pInfo.validDiscount = true; // all grouped products exists insertProduct(pInfo); ///inserting each product of the group } // correct fields }//for each element } else insertProduct(info); resetEdits(); ui->editCode->setFocus(); } }
void PurchaseEditor::doPurchase() { if (!db.isOpen()) db.open(); if (!db.isOpen()) {return;} QStringList items; items.clear(); //temporal items list items.append("empty list"); //just a tweak for creating the transaction, cleaning after creating it. Azahar *myDb = new Azahar; myDb->setDatabase(db); qDebug()<<"doPurchase..."; qDebug()<<"DATE:"<<getDate().toString()<<getTime().toString(); TransactionInfo tInfo; if (getPurchased()) { tInfo.type = tBuy; } else { tInfo.type = tDonation; } tInfo.amount = getTotalBuy(); tInfo.date = getDate(); tInfo.time = getTime(); tInfo.paywith = 0.0; tInfo.changegiven = 0.0; tInfo.paymethod = pCash; tInfo.state = tCompleted; tInfo.userid = loggedUserId; tInfo.clientid= 0; tInfo.cardnumber = "-NA-"; tInfo.cardauthnum = "-NA-"; tInfo.itemcount = getItemCount(); tInfo.itemlist = items.join(";"); tInfo.utility = 0; //FIXME: utility is calculated until products are sold, not before. tInfo.terminalnum = 0; //NOTE: Not really a terminal... from admin computer. tInfo.providerid = 1; //FIXME! tInfo.specialOrders = ""; tInfo.balanceId = 0; tInfo.donor = getDonor(); tInfo.note= getNote(); qulonglong trnum = myDb->insertTransaction(tInfo); //to get the transaction number to insert in the log. if ( trnum <= 0 ) { qDebug()<<"ERROR: Could not create a Purchase Transaction ::doPurchase()"; qDebug()<<"Error:"<<myDb->lastError(); //TODO: Notify the user about the error. } //Now cleaning the items to fill with real items... items.clear(); //assigning new transaction id to the tInfo. tInfo.id = trnum; QHash<QString, ProductInfo> hash = getHash(); ProductInfo info; TransactionItemInfo tItemInfo; //Iterate the hash QHashIterator<QString, ProductInfo> i(hash); int j=-1; while (i.hasNext()) { j+=1; i.next(); info = i.value(); double oldstockqty = info.stockqty; info.stockqty = info.purchaseQty+oldstockqty; //Modify data on mysql... //validDiscount is for checking if product already exists on db. see line # 396 of purchaseeditor.cpp if (info.validDiscount) { if (!myDb->updateProduct(info, info.code)) qDebug()<<myDb->lastError(); else { //FIXME: loggedUserId, logging in widgets!? myDb->insertLog(loggedUserId, QDate::currentDate(), QTime::currentTime(), "[PURCHASE] "+i18n("Purchase #%4 - %1 x %2 (%3)", info.purchaseQty, info.desc, info.code, trnum)); qDebug()<<"Product updated [purchase] ok..."<<i18n("Purchase #%4 - %1 x %2 (%3)", info.purchaseQty, info.desc, info.code, trnum); } } else { if (!myDb->insertProduct(info)) qDebug()<<myDb->lastError(); else { myDb->insertLog(loggedUserId, QDate::currentDate(), QTime::currentTime(), "[PURCHASE] "+i18n("Purchase #%4 - [new] - %1 x %2 (%3)", info.purchaseQty, info.desc, info.code, trnum) ); qDebug()<<i18n("Purchase #%4 - [new] - %1 x %2 (%3)", info.purchaseQty, info.desc, info.code, trnum); } } ui->p->m_model->select(); items.append(info.code+"/"+QString::number(info.purchaseQty)); // Compiling transactionitems tItemInfo.transactionid = tInfo.id; tItemInfo.position = j; tItemInfo.productCode = i.key(); tItemInfo.unitStr = info.unitStr; tItemInfo.qty = info.purchaseQty; tItemInfo.cost = info.cost; tItemInfo.price = info.price; tItemInfo.disc = info.disc * info.purchaseQty; tItemInfo.total = info.cost * info.purchaseQty; tItemInfo.completePayment = true; if (info.isAGroup) tItemInfo.name = info.desc.replace("\n", "|"); else tItemInfo.name = info.desc; tItemInfo.isGroup = info.isAGroup; myDb->insertTransactionItem(tItemInfo); } //update items in transaction data tInfo.itemlist = items.join(";"); myDb->updateTransaction(tInfo); delete myDb; }