纳入特性和功能

本文介绍了集成新交易所必须实现的特性和功能。

税务集成支持以下特性和功能:

  • 覆盖销售税
  • 多个增值税 ID
  • 清单代码
  • 现金折扣

覆盖销售税

在税务集成中,您无法在一行上编辑税组和项目税组,因为税是由税务计算服务确定的。 覆盖销售税组 功能允许您更改行上指定的税组或项目税组以计算销售税。 此计算将覆盖由税务计算服务确定的税组。

覆盖销售税 选项设置为 时,您可以选择特定的税组和项目税组进行税务计算。

覆盖销售税选项设置为“是”。

按照以下步骤启用该功能。

  1. 覆盖销售税 字段添加到交易明细表架构和 销售税 部分(如果存在)。

    覆盖添加到交易明细表架构的销售税字段。

  2. 在相关交易表单上将默认可见性设置为 false

  3. 覆盖销售税 字段映射到 SalesPurchJournalLine 地图。 此图在税务一体化中被广泛使用。 如果没有映射,则可能需要额外的代码来实现预期的功能。

  4. 设置交易表单的可见性和可编辑性:

    • 在交易表单数据源上将默认可见性设置为 false

    • 仅当此交易启用税务整合时,才将默认可见性设置为 true

      if (isTaxIntegrationEnabledForPurchase) // Condition should be modified according to the business process
      {
          PurchTable_ds.object(fieldNum(PurchTable, OverrideSalesTax)).visible(true);
          PurchLine_ds.object(fieldNum(PurchLine, OverrideSalesTax)).visible(true);
      }
      
    • 向交易表单添加 allowEdit 控件,用于控制税组和物料税组的可编辑性。 通常有三个地方可以添加此控件:

      • 形式为 init() 的方法
      • active 线的方法
      • modified() 覆盖销售税 字段的方法
      if (isTaxIntegrationEnabledForPurchase) // Condition should be modified according to the business process
      {
          PurchLine_ds.object(fieldNum(PurchLine, TaxGroup)).allowEdit(purchLine.OverrideSalesTax == NoYes::Yes);
          PurchLine_ds.object(fieldNum(PurchLine, TaxItemGroup)).allowEdit(purchLine.OverrideSalesTax == NoYes::Yes);
      }
      
  5. 在数据检索活动中设置覆盖销售税的值。

    line.setOverrideSalesTax(this.vendInvoiceInfoLine.OverrideSalesTax);

  6. 为了保持设计的一致性,新的费用将输入其来源的默认覆盖销售税。 修改 MarkupTrans::getOverrideSalesTaxFromParentRecord(MarkupTransRefTableId _tableId, MarkupTransRefRecId _refRecId) 以获得新的交易支持。

  7. 可选:修改相关实体以支持覆盖销售税的导入和导出。

多个增值税 ID

多重增值税 ID 功能允许通过税务计算服务确定增值税(VAT)ID。 此功能由 支持多个增值税登记号 功能控制。 有关详细信息,请参阅多个增值税登记编号

在功能管理中支持多个增值税登记号功能。

此功能必须确定并保存两个注册号:当前法人实体的税务机关注册号和交易对手的注册号。 如果交易没有客户或供应商作为交易对手,则交易对手登记号将不起作用。

注释

一笔交易的所有行均仅有一个法人机构登记号码和一个交易对手登记号码。 该功能的大部分代码在 TaxIntegrationTaxIdActivityOnDocument.xpp中完成。

数据库架构

TaxIdPartyTaxId 数据字段用于注册号的记录 ID。 这两个字段被添加到以下相关表中,用于存储交易的注册号:

  • 多伦多税务工作运输局
  • 未承诺纳税
  • 税务通
  • 客户装箱单
  • CustInvoiceJour
  • 出售装箱单
  • 售票处

上述列表中的前三个表(与税务相关的表)是行级表,而后四个是标题级表,因为一笔交易应该具有相同的登记号。

法人实体登记号由 支持多个增值税登记号 功能启用。 这里对于新交易没有任何要求。 如果税码已确定,则法人登记号码将填写分配给该税码的结算期的登记号码。 它在 TaxIntegrationTaxIdActivityOnDocument::populateTaxLineTaxId() 处确定并与税务结果一起保存到数据库中。

还有针对法人实体注册号的验证逻辑,以防交易中不同行确定不同的注册号。 此验证在 TaxIntegrationTaxIdActivityOnDocument::checkTaxIdConsistency()完成。

交易对手登记号码

交易对手登记号由税务计算服务确定。 收到答复后,验证该号码并将其与法人实体注册号一起保存到数据库中。 但是,如果税务计算服务确定的数字不在用户的主数据中,则交易抬头上的默认值将被写入数据库,而不是返回的值。 交易对手登记号并不适用于所有交易。 然而,还有额外的逻辑来处理这种方法。

默认逻辑

从客户和供应商主数据到交易头都有默认逻辑。 您可以设置 免税号码 客户和供应商主数据级别的价值。 当创建新交易时,将输入默认的免税号码。 但是,您可以选择一个新号码来覆盖默认号码。 如果税务服务返回的数字无效,则税务计算之前标题上的数字将用作默认数字。

免税号码是一个字符串字段(增值税号) 而不是记录 ID,它有两个数据源。 一个数据来源是税务登记号,另一个数据来源是免税号码。 税务集成仅支持税务登记号作为其来源。 两个新领域, 增值税号记录增值税号表类型,应添加到适当的表中以区分记录。

添加新交易时,决定是否应将 VATNumVATNumRecIdVATNumTableType 字段添加到交易头表。 如果需要添加,也请添加表格 TaxExemptVATNumMap。 当用户在用户界面(UI)中选择一个数字时,记录 ID 和表类型将自动保存到标题表中。

开发人员必须识别默认逻辑并调用 copyPrimaryRegistrationNumberToVATMap 将两个字段复制到新创建的交易头表中。 使用以下从 CustTableSalesTable 的默认代码作为 SalesTable.xpp中的示例。

private void initRegistrationNumbers(CustTable _custTable)
{
    this.vatNum = _custTable.getPrimaryRegistrationNumber(TaxRegistrationTypesList::TAXID);
    _custTable.copyPrimaryRegistrationNumberToVATMap(this);     // This line is to copy the new fields.
    this.EnterpriseNumber = _custTable.getPrimaryRegistrationNumber(TaxRegistrationTypesList::UID);
}

切换功能

  1. 修改 switch 函数以支持日记帐过程中的新交易:

    TaxIntegrationUtils::isMultipleTaxIdEnabledForJournalV3(RefTableId _journalHeaderTableId, RefRecId _journalHeaderRecId, Tax _tax = null)

  2. 如果没有交易对手,或者交易对手登记号不适用于新交易,则跳过 TaxIntegrationTaxIdActivityOnDocument::shouldSetPartyTaxId()处的交易对手逻辑。

    protected static boolean shouldSetPartyTaxId(TaxIntegrationDocumentObject _document)
    {
        // Sales quotation for a prospect customer doesn't apply to the counterparty VAT ID
        if (_document.getHeadingTableId() == tableNum(SalesQuotationTable) && _document.getCustVendAccount() == '')
            return false;
        // Currently for purchase order and sales order, the party tax ID is set only if returned by the tax service.
        // For Transfer Order, its party tax ID isn't determined by the tax service and must be set for the first calculation round.
        return _document.isPartyTaxIdReturned()
            || ((_document.getBusinessProcess() == TaxIntegrationBusinessProcess::Inventory)
                && !(TaxInventTransferCalcTaxContext::current() && TaxInventTransferCalcTaxContext::current().parmShouldSkipSetPartyTaxId()))
            // If a default exists, always go through the tax ID process.
            || _document.getPartyTaxIdRecIdDefault();
    }
    

编号规则组

数字序列组是 多重增值税 ID 功能的一部分。 当交易抬头上的增值税 ID 更新时,相应的编号序列组也应更新。 但此更新并不适用于所有交易。 如果应将编号序列组集成到新的交易中,请在数据持久性活动中使用以下示例。

private void saveNumberSequenceGroupToTable()
{
    NumberSequenceGroupId numberSequenceGroupId = document.getNumberSequenceGroupId();
    if (numberSequenceGroupId && custInvoiceTable.numberSequenceGroup != numberSequenceGroupId)
    {
        ttsbegin;
        custInvoiceTable.numberSequenceGroup = document.getNumberSequenceGroupId();
        custInvoiceTable.doUpdate();
        ttscommit;
    }
}

所有交易的税务识别活动均已确定。 在数据持久化活动中添加并调用逻辑来持久化数字序列组。

清单代码

清单代码类似于交易对手增值税 ID,因为两者都由服务确定并保留在数据库中。 如果在监管配置服务(RCS)中配置了列表代码适用性矩阵,则列表代码功能始终启用。

数据检索

检索默认列表代码为 TaxIntegrationDocument。 在新创建的数据检索类的 copyToDocumentFromHeaderTable 方法中添加一行。

protected void copyToDocumentFromHeaderTable()
{
    super();
    ...
    document.setListCode(this.purchTable.ListCode);
    ...
}

将列表代码映射到地图

数据持久类中使用 SalesPurchJournalTable map 来减少重复代码。 将标题表中的列表代码映射到地图。

<AxTableMapping>
<MappingTable>SalesPurchJournalTable</MappingTable>
    <Connections>
        ...
        <AxTableMappingConnection>
            <MapField>ListCode</MapField>
            <MapFieldTo>ListCode</MapFieldTo>
        </AxTableMappingConnection>
    </Connections>
</AxTableMapping>

如果您的交易表未映射到此 SalesPurchJournalTable 映射,请在数据持久性活动中编写您自己的逻辑来更新列表代码。

数据持久性

在新建的数据持久类的 TaxIntegrationListCodeUtility::saveListCodeFromDocumentToTable() 方法中调用 saveDocument 方法。

/// <summary>
/// Saves the document.
/// </summary>
/// <returns>Always true.</returns>
protected boolean saveDocument()
{
    TaxIntegrationTaxIdUtility::saveTaxIDFromDocumentToTable(document, salesTable);
    TaxIntegrationListCodeUtility::saveListCodeFromDocumentToTable(document, salesTable);
    return true;
}

货币兑换、四舍五入和差额调整

默认情况下启用此功能。 在单据对象中设置交易货币、报告货币的固定汇率以及会计货币的固定汇率。 此操作由 TaxIntegrationCurrencyExchangeActivityOnDocument 活动完成,该活动在 TaxIntegrationFacade中无任何条件调用。 您不需要采取任何行动即可使用此功能。

现金折扣

如果您的财务和运营应用程序中的新交易已经支持现金折扣功能,则税务集成还可以让税务计算服务确定现金折扣参数。 以下是启用此功能的过程的简要概述。

  1. 在代码库中,找到所有现金折扣参数的引用。

  2. 将现金折扣参数的引用替换为税务计算服务的参数。 可以通过以下两种方法之一检索参数:

    • TaxIntegrationFacade:: getTaxJurisdictionParameters(RefTableId _sourceHeadingTableId, RefRecId _sourceHeadingRecId)
    • TaxIntegrationFacade::getTaxJurisdictionParametersByTable(Common _sourceHeadingTable)
  3. 扩展开关功能以启用新交易:

    • TaxIntegrationUtils::shouldRetrieveCashDiscParametersFromTaxService(RefTableId _refTableId, RefRecId _refRecId)
    • TaxIntegrationUtils::getBusinessProcessBySourceHeadingTable(RefTableId _sourceHeadingTableId, RefRecId _sourceHeadingRecId)