TR单据自动生成TO单并确认

本文介绍了一种自动化流程,通过使用特定的参数和数据字段,如仓库号、TR号、项目、数量等,自动生成TO单据并进行确认。此过程涉及调用'L_TO_CREATE_TR'函数,并处理多种可能的异常情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

TR单据自动生成TO单并确认

 LS_LTBK-LGNUM = GS_OUTPUT-LGNUM.               "仓库号
      LS_LTBK-TBNUM = GS_OUTPUT-TBNUM.               "TR
       LT_FUN_IT_TRITE-TBPOS = GS_OUTPUT-TBPOS."     TR项目
      LT_FUN_IT_TRITE-ANFME = GS_OUTPUT-MENGE."     实际数量
      LT_FUN_IT_TRITE-ALTME = GS_OUTPUT-MEINS."

**      LT_FUN_IT_TRITE-LETYP =                    "仓储单位类型

      LT_FUN_IT_TRITE-CHARG = GS_OUTPUT-CHARG."      收货批次
      LT_FUN_IT_TRITE-NLTYP = GS_OUTPUT-NLTYP."      目的仓储类型
      LT_FUN_IT_TRITE-NLPLA = GS_OUTPUT-NLPLA."       目的仓位
      LT_FUN_IT_TRITE-VLTYP = GS_OUTPUT-VLTYP."      源发仓储类型
      LT_FUN_IT_TRITE-VLPLA = GS_OUTPUT-VLPLA.       " 源发仓位
      LT_FUN_IT_TRITE-NLBER =  '001'.                 "目的地仓储区
      APPEND LT_FUN_IT_TRITE.

 CALL FUNCTION 'L_TO_CREATE_TR'
      EXPORTING
        I_LGNUM                        = 
LS_LTBK-LGNUM "仓库号
        I_TBNUM                        = LS_LTBK-TBNUM " TR
*       I_REFNR                        = ' '

        I_SQUIT                        = 'X'

*       I_NIDRU                        = ' '
*       I_DRUKZ                        = ' '
*       I_LDEST                        = ' '
*       I_TBELI                        = ' '
*       I_NOSPL                        = ' '
*       I_UPDATE_TASK                  = ' '
*       I_COMMIT_WORK                  = 'X'

        I_BNAME                        = SY-UNAME

*       I_TEILK                        = ' '
*       I_SOLEX                        = 0
*       I_PERNR                        = 0
*       I_RSNUM                        = ' '
*       I_LDEST_LANG                   = ' '

        IT_TRITE                       = LT_FUN_IT_TRITE[]
      IMPORTING
        E_TANUM                        = LV_FUN_TANUM

*       E_TEILK                        =

      TABLES
        T_LTAK                         = LT_FUN_LTAK_VB
        T_LTAP_VB                      = LT_FUN_LTAP_VB
        T_WMGRP_MSG                    = LT_FUN_WMGRP_MSG
      EXCEPTIONS
        FOREIGN_LOCK                   = 1
        QM_RELEVANT                    = 2
        TR_COMPLETED                   = 3
        XFELD_WRONG                    = 4
        LDEST_WRONG                    = 5
        DRUKZ_WRONG                    = 6
        TR_WRONG                       = 7
        SQUIT_FORBIDDEN                = 8
        NO_TO_CREATED                  = 9
        UPDATE_WITHOUT_COMMIT          = 10
        NO_AUTHORITY                   = 11
        PREALLOCATED_STOCK             = 12
        PARTIAL_TRANSFER_REQ_FORBIDDEN = 13
        INPUT_ERROR                    = 14
        ERROR_MESSAGE                  = 16
        OTHERS                         = 15.

#include "widget.h" #include "ui_widget.h" #include <QtDebug> #include <QDateTime> #include <QInputDialog> #include <sstream> #include <iomanip> #include <algorithm> #include <cmath> Widget::Widget(QWidget *parent) : QWidget(parent) , ui(new Ui::Widget) , currentMode(NONE) , currentBillIndex(-1) { ui->setupUi(this); // 初始化日期时间为当前时间 ui->dateTimeEdit->setDateTime(QDateTime::currentDateTime()); // 设置文本浏览器为只读 ui->textBrowser->setReadOnly(true); // 初始化操作状态 currentMode = NONE; currentBillIndex = -1; } Widget::~Widget() { delete ui; } // 商品录入按钮 void Widget::on_pushButton_clicked() { currentMode = ADD_ITEM; ui->textBrowser->setHtml("<h3>商品录入模式</h3>" "<p>请在输入框中填写商品信息,然后点击<strong>确认</strong>按钮。</p>" "<p>点击<strong>取消</strong>按钮退出此模式。</p>"); } // 买入按钮 void Widget::on_pushButton_2_clicked() { if (items.empty()) { QMessageBox::warning(this, "操作失败", "没有商品可购买"); return; } currentMode = BUY_ITEMS; // 生成预览 double total = 0; std::stringstream ss; ss << "<h3>买入操作 - 账预览</h3>"; ss << "<table border='1' style='border-collapse: collapse; width: 100%;'>"; ss << "<tr><th>商品名称</th><th>数量</th><th>价</th><th>小计</th></tr>"; for (const Item& item : items) { double subtotal = item.quantity * item.price; total += subtotal; ss << "<tr><td>" << item.name << "</td><td>" << item.quantity << "</td><td>" << std::fixed << std::setprecision(2) << item.price << "</td><td>" << std::fixed << std::setprecision(2) << subtotal << "</td></tr>"; } ss << "<tr><td colspan='3' align='right'><strong>总计:</strong></td><td>" << std::fixed << std::setprecision(2) << total << "</td></tr>"; ss << "</table>"; ss << "<p>点击<strong>确认</strong>按钮完成购买,点击<strong>取消</strong>按钮放弃。</p>"; ui->textBrowser->setHtml(QString::fromStdString(ss.str())); } // 账按钮 void Widget::on_pushButton_3_clicked() { updateBillDisplay(); } // 退货按钮 void Widget::on_pushButton_4_clicked() { if (bills.empty()) { QMessageBox::warning(this, "操作失败", "没有可退货的账"); return; } currentMode = RETURN_ITEMS; showReturnForm(); } // 显示退货表 void Widget::showReturnForm() { std::stringstream ss; ss << "<h3>退货操作</h3>"; // 显示账列表供选择 if (currentMode == RETURN_ITEMS) { ss << "<p>请选择要退货的账:</p>"; ss << "<table border='1' style='border-collapse: collapse; width: 100%;'>"; ss << "<tr><th>ID</th><th>日期</th><th>总金额</th><th>类型</th><th>状态</th></tr>"; for (size_t i = 0; i < bills.size(); i++) { if (!bills[i].isReturn) { // 只显示销售账 std::string status = "可退货"; if (bills[i].isFullyReturned) { status = "<span style='color:gray'>已完全退货</span>"; } ss << "<tr><td><a href='bill:" << i << "'>" << bills[i].id << "</a></td>" << "<td>" << bills[i].time << "</td>" << "<td>" << std::fixed << std::setprecision(2) << bills[i].total << "</td>" << "<td>" << (bills[i].isReturn ? "退货" : "销售") << "</td>" << "<td>" << status << "</td></tr>"; } } ss << "</table>"; } // 显示选中的账详情和退货输入框 else if (currentMode == RETURN_ITEM_SELECTED && currentBillIndex >= 0) { const Bill& bill = bills[currentBillIndex]; // 检查账是否已完全退货 if (bill.isFullyReturned) { ss << "<div style='color:red; background-color:#FFE4E1; padding:10px; border-radius:5px;'>" << "<strong>警告:此账已完全退货,无法再次退货!</strong>" << "</div>"; ui->textBrowser->setHtml(QString::fromStdString(ss.str())); return; } ss << "<p><strong>选择的账: " << bill.id << "</strong></p>"; ss << "<p>请输入要退货的商品信息:</p>"; // 显示账商品列表 ss << "<table border='1' style='border-collapse: collapse; width: 100%;'>"; ss << "<tr><th>商品名称</th><th>购买数量</th><th>价</th><th>可退数量</th><th>状态</th></tr>"; for (const Item& item : bill.items) { std::string status = "可退货"; std::string key = bill.id + "_" + item.name; // 检查商品是否已完全退货 if (returnedItems.find(key) != returnedItems.end()) { status = "<span style='color:gray'>已退货</span>"; } ss << "<tr><td>" << item.name << "</td><td>" << item.quantity << "</td><td>" << std::fixed << std::setprecision(2) << item.price << "</td><td>" << item.quantity << "</td><td>" << status << "</td></tr>"; } ss << "</table>"; // 退货输入提示 ss << "<p style='margin-top: 15px;'>" << "请在下方输入框中填写:<br>" << "1. <strong>商品名称</strong>(必须与账中一致)<br>" << "2. <strong>退货数量</strong>(不能超过可退数量)<br>" << "3. <strong>商品价</strong>(需与原价一致)" << "</p>"; // 添加退货记录提示 if (!returnedItems.empty()) { ss << "<div style='background-color:#F0F8FF; padding:5px; margin-top:10px;'>" << "<strong>注意:</strong>已退货的商品标记为<span style='color:gray'>已退货</span>,不能重复退货" << "</div>"; } } ui->textBrowser->setHtml(QString::fromStdString(ss.str())); } // 日结按钮 void Widget::on_pushButton_5_clicked() { showDailySummary(); } // 确认按钮 void Widget::on_pushButton_6_clicked() { switch (currentMode) { case ADD_ITEM: { QString name = ui->lineEdit->text(); QString quantity = ui->lineEdit_2->text(); QString price = ui->lineEdit_3->text(); if (name.isEmpty() || quantity.isEmpty() || price.isEmpty()) { QMessageBox::warning(this, "输入错误", "请填写完整的商品信息"); return; } bool ok; int qty = quantity.toInt(&ok); if (!ok || qty <= 0) { QMessageBox::warning(this, "输入错误", "数量必须是正整数"); return; } double prc = price.toDouble(&ok); if (!ok || prc <= 0) { QMessageBox::warning(this, "输入错误", "价必须是正数"); return; } Item newItem = {name.toStdString(), qty, prc}; items.push_back(newItem); QMessageBox::information(this, "成功", "商品已添加到列表"); updateItemDisplay(); clearInputFields(); break; } case BUY_ITEMS: { // 生成ID和时间 QString id = QString::number(bills.size() + 1); QString time = ui->dateTimeEdit->dateTime().toString("yyyy-MM-dd hh:mm:ss"); // 计算总金额 double total = 0; for (const Item& item : items) { total += item.quantity * item.price; } // 创建新账 Bill newBill = {id.toStdString(), time.toStdString(), items, total, false}; bills.push_back(newBill); // 清空购物车 items.clear(); QMessageBox::information(this, "交易成功", QString("账创建成功!\n账号: %1\n总金额: %2").arg(id).arg(total, 0, 'f', 2)); updateItemDisplay(); updateBillDisplay(); currentMode = NONE; break; } case RETURN_ITEMS: { if (currentBillIndex < 0 || currentBillIndex >= static_cast<int>(bills.size())) { QMessageBox::warning(this, "操作失败", "请先选择要退货的账"); return; } Bill& bill = bills[currentBillIndex]; // 创建退货账 QString returnId = QString::number(bills.size() + 1); QString time = ui->dateTimeEdit->dateTime().toString("yyyy-MM-dd hh:mm:ss"); // 简化处理:全额退货 Bill returnBill = {returnId.toStdString(), time.toStdString(), bill.items, bill.total, true}; bills.push_back(returnBill); QMessageBox::information(this, "退货成功", QString("退货完成!\n退货号: %1\n退款金额: %2").arg(returnId).arg(bill.total, 0, 'f', 2)); updateBillDisplay(); currentMode = NONE; currentBillIndex = -1; break; } case RETURN_ITEM_SELECTED: { if (currentBillIndex < 0 || currentBillIndex >= static_cast<int>(bills.size())) { QMessageBox::warning(this, "操作失败", "请先选择要退货的账"); return; } Bill& originalBill = bills[currentBillIndex]; // 检查账是否已完全退货 if (originalBill.isFullyReturned) { QMessageBox::warning(this, "操作失败", QString("账 %1 已完全退货,无法再次退货!") .arg(QString::fromStdString(originalBill.id))); return; } // 获取退货商品信息 QString itemName = ui->lineEdit->text(); QString returnQtyStr = ui->lineEdit_2->text(); QString itemPriceStr = ui->lineEdit_3->text(); if (itemName.isEmpty() || returnQtyStr.isEmpty() || itemPriceStr.isEmpty()) { QMessageBox::warning(this, "输入错误", "请填写完整的退货信息"); return; } bool ok; int returnQty = returnQtyStr.toInt(&ok); if (!ok || returnQty <= 0) { QMessageBox::warning(this, "输入错误", "退货数量必须是正整数"); return; } double itemPrice = itemPriceStr.toDouble(&ok); if (!ok || itemPrice <= 0) { QMessageBox::warning(this, "输入错误", "商品价必须是正数"); return; } // 在原始账中查找该商品 auto itemIt = std::find_if(originalBill.items.begin(), originalBill.items.end(), [&](const Item& item) { return item.name == itemName.toStdString(); }); if (itemIt == originalBill.items.end()) { QMessageBox::warning(this, "商品不存在", QString("在账 %1 中找不到商品 '%2'") .arg(QString::fromStdString(originalBill.id), itemName)); return; } // 检查商品是否已完全退货 std::string itemKey = originalBill.id + "_" + itemIt->name; if (returnedItems.find(itemKey) != returnedItems.end()) { QMessageBox::warning(this, "商品已退货", QString("商品 '%1' 在此账中已完全退货,无法再次退货!") .arg(itemName)); return; } // 验证退货数量 if (returnQty > itemIt->quantity) { QMessageBox::critical(this, "退货数量超出", QString("<b>退货数量超过购买数量!</b><br><br>" "商品: %1<br>" "购买数量: %2<br>" "退货数量: %3<br>" "超出数量: %4") .arg(itemName) .arg(itemIt->quantity) .arg(returnQty) .arg(returnQty - itemIt->quantity)); return; } // 验证商品价 if (std::abs(itemPrice - itemIt->price) > 0.01) { QMessageBox::warning(this, "价不匹配", QString("输入价与购买价不一致!<br><br>" "商品: %1<br>" "购买价: %2<br>" "输入价: %3") .arg(itemName) .arg(itemIt->price, 0, 'f', 2) .arg(itemPrice, 0, 'f', 2)); return; } // 计算退货金额 double returnAmount = returnQty * itemPrice; // 更新原始账 itemIt->quantity -= returnQty; originalBill.total -= returnAmount; // 检查商品是否完全退货 if (itemIt->quantity <= 0) { // 标记商品已完全退货 returnedItems.insert(itemKey); // 从账中移除商品 originalBill.items.erase(itemIt); // 检查账是否完全退货 if (originalBill.items.empty()) { originalBill.isFullyReturned = true; } } // 创建退货账 QString returnId = QString::number(bills.size() + 1); QString time = ui->dateTimeEdit->dateTime().toString("yyyy-MM-dd hh:mm:ss"); // 退货账只包含退货的商品 std::vector<Item> returnItems; returnItems.push_back({itemName.toStdString(), returnQty, itemPrice}); Bill returnBill = {returnId.toStdString(), time.toStdString(), returnItems, returnAmount, true}; bills.push_back(returnBill); QMessageBox::information(this, "退货成功", QString("<b>退货成功!</b><br><br>" "退货号: %1<br>" "商品: %2<br>" "数量: %3<br>" "价: %4<br>" "退款金额: %5") .arg(returnId) .arg(itemName) .arg(returnQty) .arg(itemPrice, 0, 'f', 2) .arg(returnAmount, 0, 'f', 2)); updateBillDisplay(); currentMode = RETURN_ITEMS; showReturnForm(); break; } default: QMessageBox::information(this, "提示", "请先选择要执行的操作"); } } // 取消按钮 void Widget::on_pushButton_7_clicked() { currentMode = NONE; currentBillIndex = -1; ui->textBrowser->clear(); clearInputFields(); } // 时间变化 void Widget::on_dateTimeEdit_dateChanged(const QDate &date) { // 更新显示时使用当前选择的日期 if (currentMode == NONE) { showDailySummary(); } } void Widget::on_textBrowser_anchorClicked(const QUrl &arg1) { QString url = arg1.toString(); if (url.startsWith("bill:")) { QString indexStr = url.mid(5); bool ok; int index = indexStr.toInt(&ok); if (ok && index >= 0 && index < static_cast<int>(bills.size())) { currentBillIndex = index; currentMode = RETURN_ITEM_SELECTED; showReturnForm(); // 清空输入框 clearInputFields(); } } } // 更新账显示 void Widget::updateBillDisplay() { std::stringstream ss; ss << "<h3>账列表</h3>"; if (bills.empty()) { ss << "<p>没有账</p>"; } else { ss << "<table border='1' style='border-collapse: collapse; width: 100%;'>"; ss << "<tr><th>ID</th><th>日期</th><th>总金额</th><th>类型</th><th>状态</th><th>操作</th></tr>"; for (size_t i = 0; i < bills.size(); i++) { std::string status = ""; if (bills[i].isFullyReturned) { status = "<span style='color:green'>已完全退货</span>"; } else if (!bills[i].isReturn && bills[i].items.empty()) { status = "<span style='color:gray'>无商品</span>"; } ss << "<tr><td>" << bills[i].id << "</td>" << "<td>" << bills[i].time << "</td>" << "<td>" << std::fixed << std::setprecision(2) << bills[i].total << "</td>" << "<td>" << (bills[i].isReturn ? "退货" : "销售") << "</td>" << "<td>" << status << "</td>" << "<td><a href='bill:" << i << "'>查看详情</a></td></tr>"; } ss << "</table>"; } ui->textBrowser->setHtml(QString::fromStdString(ss.str())); } // 更新商品显示 void Widget::updateItemDisplay() { std::stringstream ss; ss << "<h3>当前商品列表</h3>"; if (items.empty()) { ss << "<p>没有商品</p>"; } else { ss << "<table border='1' style='border-collapse: collapse; width: 100%;'>"; ss << "<tr><th>商品名称</th><th>数量</th><th>价</th></tr>"; for (const Item& item : items) { ss << "<tr><td>" << item.name << "</td><td>" << item.quantity << "</td><td>" << std::fixed << std::setprecision(2) << item.price << "</td></tr>"; } ss << "</table>"; } ui->textBrowser->setHtml(QString::fromStdString(ss.str())); } // 显示账详情 void Widget::showBillDetails(const Bill& bill) { std::stringstream ss; ss << "<h3>账详情 - " << bill.id << "</h3>"; ss << "<p><strong>日期:</strong> " << bill.time << "</p>"; ss << "<p><strong>类型:</strong> " << (bill.isReturn ? "退货" : "销售") << "</p>"; ss << "<table border='1' style='border-collapse: collapse; width: 100%;'>"; ss << "<tr><th>商品名称</th><th>数量</th><th>价</th><th>小计</th></tr>"; for (const Item& item : bill.items) { double subtotal = item.quantity * item.price; ss << "<tr><td>" << item.name << "</td><td>" << item.quantity << "</td><td>" << std::fixed << std::setprecision(2) << item.price << "</td><td>" << std::fixed << std::setprecision(2) << subtotal << "</td></tr>"; } ss << "<tr><td colspan='3' align='right'><strong>总计:</strong></td><td>" << std::fixed << std::setprecision(2) << bill.total << "</td></tr>"; ss << "</table>"; if (currentMode == RETURN_ITEMS && !bill.isReturn) { ss << "<p>点击<strong>确认</strong>按钮完成退货操作。</p>"; } ui->textBrowser->setHtml(QString::fromStdString(ss.str())); } // 显示日结汇总 void Widget::showDailySummary() { QDate selectedDate = ui->dateTimeEdit->date(); QString dateStr = selectedDate.toString("yyyy-MM-dd"); double totalIncome = 0; double totalReturn = 0; for (const Bill& bill : bills) { QString billDate = QString::fromStdString(bill.time).split(" ")[0]; if (billDate == dateStr) { if (!bill.isReturn) { totalIncome += bill.total; } else { totalReturn += bill.total; } } } double netIncome = totalIncome - totalReturn; std::stringstream ss; ss << "<h3>日结汇总 - " << dateStr.toStdString() << "</h3>"; ss << "<table border='1' style='border-collapse: collapse; width: 100%;'>"; ss << "<tr><th>项目</th><th>金额</th></tr>"; ss << "<tr><td>总收入</td><td>" << std::fixed << std::setprecision(2) << totalIncome << "</td></tr>"; ss << "<tr><td>总退货</td><td>" << std::fixed << std::setprecision(2) << totalReturn << "</td></tr>"; ss << "<tr><td><strong>净收益</strong></td><td><strong>" << std::fixed << std::setprecision(2) << netIncome << "</strong></td></tr>"; ss << "</table>"; ui->textBrowser->setHtml(QString::fromStdString(ss.str())); } // 清空输入框 void Widget::clearInputFields() { ui->lineEdit->clear(); ui->lineEdit_2->clear(); ui->lineEdit_3->clear(); } 检查一下日结的逻辑,出现了买完了之后再退货净收益是负值,且销售总额为0的情况,要求净收入等于销售总额减去净利润
06-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值