Jagamisviis:


Maksuintegratsiooni andmeväljade lisamine laiendite abil

See artikkel selgitab X++ laienduste kasutamist maksuintegratsiooni andmeväljade lisamiseks. Neid välju saab laiendada maksuteenuse maksuandmete mudelile ja kasutada maksukoodide määramiseks. Lisateavet vt teemast Andmeväljade lisamine maksukonfiguratsioonides.

Andmemudel

Andmemudeli andmeid teostatakse objektides ja neid rakendatakse klassides.

Suurimad objektid on järgmised.

  • AxClassi/maksuintegratsioonidokumendiobjekt
  • AxClassi/maksuintegratsioonireaobjekt
  • AxClass/TaxIntegrationiTaxLine’iobjekt

Järgmine illustratsioon näitab, kuidas need objektid on seotud.

Andmemudeli objekti seos. ]

Dokumendi objekt võib sisaldada palju reaobjekte . Iga objekt sisaldab maksuteenuse metaandmeid.

  • TaxIntegrationDocumentObject on originAddress metaandmed, mis sisaldavad teavet lähteaadressi kohta, ja metaandmed includingTax , mis näitavad, kas rea summa sisaldab käibemaksu.
  • TaxIntegrationLineObject on, itemId ja quantity metaandmed categoryId .

Paberraha

TaxIntegrationLineObject juurutab ka tasuobjekte .

Integratsiooni voog

Vooandmeid manipuleeritakse tegevustega.

Võtmetegevused

  • AxClass/TaxIntegrationi arvutamiseactivityOnDocument
  • AxClass/MaksuintegratsioonivaluutaExchangeActivityOnDocument
  • AxClass/TaxIntegrationDataPersistenceActivityOnDocument
  • AxClass/TaxIntegrationDataRetrievalActivityOnDocument
  • AxClass/TaxIntegration settingRetrievalActivityOnDocument

Tegevused käivitatakse järgmises järjestuses.

  1. Sätte toomine
  2. Andmete toomine
  3. Arvutusteenus
  4. Valuutavahetus
  5. Andmete püsivus

Näiteks laiendage andmete toomist enne arvutusteenust .

Andmete toomise tegevused

Andmete toomise tegevused toob andmeid andmebaasist. Erinevate kannete adapterid on saadaval andmete toomiseks erinevatest kandetabelitest:

  • AxClass/TaxIntegrationPurchTableDataRetrieval
  • AxClass/TaxIntegrationPurchParmTableDataRetrieval
  • AxClass/TaxIntegrationPurchREQTableDataRetrieval
  • AxClass/TaxIntegrationPurchRFQTableDataRetrieval
  • AxClass/TaxIntegrationVendInvoiceInfoTableDataRetrieval
  • AxClass/TaxIntegrationSalesTableDataRetrieval
  • AxClass/TaxIntegrationSalesParmDataRetrieval

Neis andmete toomise tegevustes kopeeritakse andmed andmebaasist üksusesse TaxIntegrationDocumentObject ja. TaxIntegrationLineObject Kuna kõik need tegevused laiendavad abstraktset sama malliklassi, on neil tavalised meetodid.

Arvutusteenuse jälgimine

Kalkulatsiooniteenuse tegevus on linkima maksuteenuse ja maksuintegratsiooni vaheline tegevus. See tegevus vastutab järgmiste funktsioonide eest.

  1. Taotluse koostamine.
  2. Sisestage taotlus maksuteenusesse.
  3. Saate vastuse maksuteenuselt.
  4. Sõeluge vastus.

Andmeväli, mille lisate taotlusele, sisestatakse koos teiste metaandmetega.

Laiendi rakendamine

Selles jaotises esitatakse üksikasjalikud sammud, mis selgitavad, kuidas laiendust rakendada. See kasutab näidetena kulukeskust ja projekti finantsdimensioone.

Toiming 1. Lisa andmemuutuja objektiklassi

Objektiklass sisaldab andmemuutujat ja andmete tooja/määraja meetodeid. Lisage andmeväli kas TaxIntegrationDocumentObject väljale või TaxIntegrationLineObject sõltuvalt välja tasemest. Järgmine näide kasutab rea taset ja faili nimi on TaxIntegrationLineObject_Extension.xpp.

Paberraha

Kui lisate andmevälja dokumendi tasemel, muutke faili nimeks TaxIntegrationDocumentObject_Extension.xpp.

[ExtensionOf(classStr(TaxIntegrationLineObject))]
final class TaxIntegrationLineObject_Extension
{
    private OMOperatingUnitNumber costCenter;
    private ProjId projectId;

    /// <summary>
    /// Gets a costCenter.
    /// </summary>
    /// <returns>The cost center.</returns>
    public final OMOperatingUnitNumber getCostCenter()
    {
        return this.costCenter;
    }

    /// <summary>
    /// Sets the cost center.
    /// </summary>
    /// <param name = "_value">The cost center.</param>
    public final void setCostCenter(OMOperatingUnitNumber _value)
    {
        this.costCenter = _value;
    }

    /// <summary>
    /// Gets a project ID.
    /// </summary>
    /// <returns>The project ID.</returns>
    public final ProjId getProjectId()
    {
        return this.projectId;
    }

    /// <summary>
    /// Sets the project ID.
    /// </summary>
    /// <param name = "_value">The project ID.</param>
    public final void setProjectId(ProjId _value)
    {
        this.projectId = _value;
    }
}

Kulukeskus ja Projekt lisatakse privaatsete muutujatena. Looge nende andmeväljade jaoks tooja- ja määrajameetodid, et andmeid manipuleerida.

Toiming 2. Tooge andmed andmebaasist

Määrake kanne ja laiendage andmete toomiseks sobivad adapteriklassid. Näiteks kui kasutate ostutellimuse kannet , peate laiendama ja TaxIntegrationPurchTableDataRetrieval TaxIntegrationVendInvoiceInfoTableDataRetrieval.

Paberraha

TaxIntegrationPurchParmTableDataRetrieval on päritud asukohast TaxIntegrationPurchTableDataRetrieval. Seda ei tohi muuta, välja arvatud juhul, kui tabelite purchTable ja tabelite loogika purchParmTable on erinev.

Kui andmeväli tuleks lisada kõigile kannetele, laiendage kõiki DataRetrieval klasse.

Kuna kõik andmete toomise tegevused laiendavad sama malliklassi, on klassistruktuurid, muutujad ja meetodid sarnased.

protected TaxIntegrationDocumentObject document;

/// <summary>
/// Copies to the document.
/// </summary>
protected abstract void copyToDocument()
{
    // It is recommended to implement as:
    //
    // this.copyToDocumentByDefault();
    // this.copyToDocumentFromHeaderTable();
    // this.copyAddressToDocument();
}
 
/// <summary>
/// Copies to the current line of the document.
/// </summary>
/// <param name = "_line">The current line of the document.</param>
protected abstract void copyToLine(TaxIntegrationLineObject _line)
{
    // It is recommended to implement as:
    //
    // this.copyToLineByDefault(_line);
    // this.copyToLineFromLineTable(_line);
    // this.copyQuantityAndTransactionAmountToLine(_line);
    // this.copyAddressToLine(_line);
    // this.copyToLineFromHeaderTable(_line);
}

Järgmine näide näitab tabeli kasutamisel põhistruktuuri PurchTable .

public class TaxIntegrationPurchTableDataRetrieval extends TaxIntegrationAbstractDataRetrievalTemplate
{
    protected PurchTable purchTable;
    protected PurchLine purchLine;

    // Query builder methods
    [Replaceable]
    protected SysDaQueryObject getDocumentQueryObject()
    [Replaceable]
    protected SysDaQueryObject getLineQueryObject()
    [Replaceable]
    protected SysDaQueryObject getDocumentChargeQueryObject()
    [Replaceable]
    protected SysDaQueryObject getLineChargeQueryObject()

    // Data retrieval methods
    protected void copyToDocument()
    protected void copyToDocumentFromHeaderTable()
    protected void copyToLine(TaxIntegrationLineObject _line)
    protected void copyToLineFromLineTable(TaxIntegrationLineObject _line)
    ...
}

Kui meetod CopyToDocument on kutsuda, on puhver this.purchTable juba olemas. Selle meetodi eesmärk on kopeerida kõik nõutud this.purchTable document andmed objekti, kasutades klassis loodud määraja meetodit DocumentObject .

Samuti on selles meetodis this.purchLine juba puhver CopyToLine olemas. Selle meetodi eesmärk on kopeerida kõik nõutud this.purchLine _line andmed objekti, kasutades klassis loodud määraja meetodit LineObject .

Kõige selgem lähenemine on laiendada meetodeid CopyToDocument ja neid CopyToLine . Soovitame siiski esmalt proovida copyToDocumentFromHeaderTable neid ja copyToLineFromLineTable meetodeid. Kui nad ei tööta vastavalt vajadusele, rakendage oma meetod ja kutsuge see sisse CopyToDocument ja. CopyToLine On kolm tavalist olukorda, kus võite kasutada seda lähenemist.

  • Kohustuslik väli on sees PurchTable või PurchLine Selles olukorras saate laiendada ja copyToDocumentFromHeaderTable copyToLineFromLineTable. Siin on näidiskood.

    /// <summary>
    /// Copies to the current line of the document from.
    /// </summary>
    /// <param name = "_line">The current line of the document.</param>
    protected void copyToLineFromLineTable(TaxIntegrationLineObject _line)
    {
        next copyToLineFromLineTable(_line);
        // if we already added XXX in TaxIntegrationLineObject
        _line.setXXX(this.purchLine.XXX);
    }
    
  • Nõutud andmed pole kande vaiketabelis. Siiski on mõned seosed vaiketabeliga ja väli on enamasti vajalik. Sellises olukorras asendage tabel getDocumentQueryObject või getLineObject tehke päringuid seose abil. Järgmises näites on väli Tarni kohe integreeritud müügitellimusega rea tasemel.

    public class TaxIntegrationSalesTableDataRetrieval
    {
        protected MCRSalesLineDropShipment mcrSalesLineDropShipment;
    
        /// <summary>
        /// Gets the query for the lines of the document.
        /// </summary>
        /// <returns>The query for the lines of the document</returns>
        [Replaceable]
        protected SysDaQueryObject getLineQueryObject()
        {
            return SysDaQueryObjectBuilder::from(this.salesLine)
                .where(this.salesLine, fieldStr(SalesLine, SalesId)).isEqualToLiteral(this.salesTable.SalesId)
                .outerJoin(this.mcrSalesLineDropShipment)
                .where(this.mcrSalesLineDropShipment, fieldStr(MCRSalesLineDropShipment, SalesLine)).isEqualTo(this.salesLine, fieldStr(SalesLine, RecId))
                .toSysDaQueryObject();
        }
    }
    

    Selles näites on mcrSalesLineDropShipment puhver deklareeritud ja päring määratletud getLineQueryObject. Päring kasutab suhet MCRSalesLineDropShipment.SalesLine == SalesLine.RecId. Selles olukorras laiendamisel saate asendada enda loodud getLineQueryObject päringuobjektiga. Kuid arvestage järgmist.

    • Kuna meetodi tagastusväärtus on getLineQueryObject , peate selle SysDaQueryObject objekti sysDa-lähenemist kasutades konstrueerima.
    • Olemasolnud tabelit ei saa eemaldada.
  • Nõutud andmed on kandetabeliga seotud keeruka liitseosega või pole seos üks ühele (1:1) vaid üks mitmele (1:N). Sellises olukorras muutuvad asjad veidi keerukamaks. See olukord kehtib näiteks finantsdimensioonide puhul.

    Sellises olukorras saate rakendada andmete toomiseks oma meetodit. Siin on failis näidiskood TaxIntegrationPurchTableDataRetrieval_Extension.xpp .

    [ExtensionOf(classStr(TaxIntegrationPurchTableDataRetrieval))]
    final class TaxIntegrationPurchTableDataRetrieval_Extension
    {
        private const str CostCenterKey = 'CostCenter';
        private const str ProjectKey = 'Project';
    
        /// <summary>
        /// Copies to the current line of the document from.
        /// </summary>
        /// <param name = "_line">The current line of the document.</param>
        protected void copyToLineFromLineTable(TaxIntegrationLineObject _line)
        {
            Map dimensionAttributeMap = this.getDimensionAttributeMapByDefaultDimension(this.purchline.DefaultDimension);
            if (dimensionAttributeMap.exists(CostCenterKey))
            {
                _line.setCostCenter(dimensionAttributeMap.lookup(CostCenterKey));
            }
            if (dimensionAttributeMap.exists(ProjectKey))
            {
                _line.setProjectId(dimensionAttributeMap.lookup(ProjectKey));
            }
            next copyToLineFromLineTable(_line);
        }
        private Map getDimensionAttributeMapByDefaultDimension(RefRecId _defaultDimension)
        {
            DimensionAttribute dimensionAttribute;
            DimensionAttributeValue dimensionAttributeValue;
            DimensionAttributeValueSetItem dimensionAttributeValueSetItem;
            Map ret = new Map(Types::String, Types::String);
    
            select Name, RecId from dimensionAttribute
                join dimensionAttributeValue
                    where dimensionAttributeValue.dimensionAttribute == dimensionAttribute.RecId
                join DimensionAttributeValueSetItem
                    where DimensionAttributeValueSetItem.DimensionAttributeValue == DimensionAttributeValue.RecId
                        && DimensionAttributeValueSetItem.DimensionAttributeValueSet == _defaultDimension;
    
            while(dimensionAttribute.RecId)
            {
                ret.insert(dimensionAttribute.Name, dimensionAttributeValue.DisplayValue);
                next dimensionAttribute;
            }
            return ret;
        }
    }
    

Toiming 3. Taotlusele andmete lisamine

Laiendage copyToTaxableDocumentHeaderWrapperFromTaxIntegrationDocumentObject taotlusele copyToTaxableDocumentLineWrapperFromTaxIntegrationLineObjectByLine andmete lisamiseks meetodit või laiendage seda. Siin on failis näidiskood TaxIntegrationCalculationActivityOnDocument_CalculationService_Extension.xpp .

[ExtensionOf(classStr(TaxIntegrationCalculationActivityOnDocument_CalculationService))]
final static class TaxIntegrationCalculationActivityOnDocument_CalculationService_Extension
{
    // Define the field name in the request
    private const str IOCostCenter = 'Cost Center';
    private const str IOProject = 'Project';
    // private const str IOEnumExample = 'Enum Example';

    /// <summary>
    /// Copies to <c>TaxableDocumentLineWrapper</c> from <c>TaxIntegrationLineObject</c> by line.
    /// </summary>
    /// <param name = "_destination"><c>TaxableDocumentLineWrapper</c>.</param>
    /// <param name = "_source"><c>TaxIntegrationLineObject</c>.</param>
    protected static void copyToTaxableDocumentLineWrapperFromTaxIntegrationLineObjectByLine(Microsoft.Dynamics.TaxCalculation.ApiContracts.TaxableDocumentLineWrapper _destination, TaxIntegrationLineObject _source)
    {
        next copyToTaxableDocumentLineWrapperFromTaxIntegrationLineObjectByLine(_destination, _source);
        // Set the field we need to integrated for tax service
        _destination.SetField(IOCostCenter, _source.getCostCenter());
        _destination.SetField(IOProject, _source.getProjectId());

        // If the field to be extended is an enum type, use enum2Symbol to convert an enum variable exampleEnum of ExampleEnumType to a string
        // _destination.SetField(IOEnumExample, enum2Symbol(enumNum(ExampleEnumType), _source.getExampleEnum()));
    }
}

Selles koodis _destination on ümbrisobjekt, mida kasutatakse taotluse loomiseks ja _source milleks on TaxIntegrationLineObject objekt.

Paberraha

Määratlege välja nimi, mida kasutatakse taotluses privaatse konstnatuurina. String peab olema täpselt sama mis maksukonfiguratsioonide artikli andmeväljadel lisatud sõlme nimi (mitte silt).

Seadke väli meetodis copyToTaxableDocumentLineWraümbrisFromTaxIntegrationLineObjectByLine meetodiga SetField . Teise parameetri andmetüüp peaks olema string. Kui andmetüüp ei ole string, teisendage see stringiks. Kui andmetüüp on X++ loend tüüp, soovitame kasutada meetodit enum2Symbol , et teisendada loend väärtus stringiks. Maksu loend lisatav väärtus peab olema täpselt sama, mis loend nimi. Järgmises loendis on erinevuste loend ettevõtte loend, sildi ja nime vahel.

  • Kauba loend koodis sümboliline nimi. enum2Symbol() saab teisendada loend väärtuse selle nimeks.
  • Vara väärtus loend täisarv.
  • Andmesildi loend olla eri eelistatud keeltes. enum2Str() saab loend selle sildiks teisendada.

Mudeli sõltuvus

Projekti edukaks loomiseks lisage mudeli sõltuvuste jaoks järgmised viitemudelid:

  • Vormi ApplicationPlatform
  • Application Kuupäev
  • Maksumootor
  • Dimensioonid, finantsdimensioon kui kasutatakse
  • Teised koodis viidatud vajalikud mudelid

Kinnitus

Pärast eelmiste sammude lõpule viimist saate oma muudatused kinnitada.

  1. Minge finantsis URL-ile ja minge aadressile Ostureskontro ja lisage&debug=vs%2CconfirmExit& . Näiteks. https://usnconeboxax1aos.cloud.onebox.dynamics.com/?cmp=DEMF&mi=PurchTableListPage&debug=vs%2CconfirmExit& Lõpp> on oluline.
  2. Avage ostutellimuse leht ja valige ostutellimuse loomiseks uus.
  3. Seadke kohandatud väljale väärtus ja seejärel valige käibemaks. Tõrkeotsingu fail eesliitega( TaxServiceTroubleshootingLog) laaditakse automaatselt alla. See fail sisaldab teenusesse maksuarvestus kandeteavet.
  4. Kontrollige, kas kohandatud väli on maksuteenuse arvutuse sisendis JSON-i jaotises olemas ja kas selle väärtus on õige. Kui väärtus ei ole õige, topeltkontrollige selle dokumendi samme.

Faili näide:

===Tax service calculation input JSON:===
{
  "TaxableDocument": {
    "Header": [
      {
        "Lines": [
          {
            "Line Type": "Normal",
            "Item Code": "",
            "Item Type": "Item",
            "Quantity": 0.0,
            "Amount": 1000.0,
            "Currency": "EUR",
            "Transaction Date": "2022-1-26T00:00:00",
            ...
            /// The new fields added at line level
            "Cost Center": "003",
            "Project": "Proj-123"
          }
        ],
        "Amount include tax": true,
        "Business Process": "Journal",
        "Currency": "",
        "Vendor Account": "DE-001",
        "Vendor Invoice Account": "DE-001",
        ...
        // The new fields added at header level, no new fields in this example
        ...
      }
    ]
  },
}
...

Lisa

Selles lisas kuvatakse täielik näidiskood finantsdimensioonide, kulukeskuse ja projekti integreerimiseks rea tasemel.

TaxIntegrationLineObject_Extension.xpp

[ExtensionOf(classStr(TaxIntegrationLineObject))]
final class TaxIntegrationLineObject_Extension
{
    private OMOperatingUnitNumber costCenter;
    private ProjId projectId;

    /// <summary>
    /// Gets a costCenter.
    /// </summary>
    /// <returns>The cost center.</returns>
    public final OMOperatingUnitNumber getCostCenter()
    {
        return this.costCenter;
    }

    /// <summary>
    /// Sets the cost center.
    /// </summary>
    /// <param name = "_value">The cost center.</param>
    public final void setCostCenter(OMOperatingUnitNumber _value)
    {
        this.costCenter = _value;
    }

    /// <summary>
    /// Gets a project ID.
    /// </summary>
    /// <returns>The project ID.</returns>
    public final ProjId getProjectId()
    {
        return this.projectId;
    }

    /// <summary>
    /// Sets the project ID.
    /// </summary>
    /// <param name = "_value">The project ID.</param>
    public final void setProjectId(ProjId _value)
    {
        this.projectId = _value;
    }
}

TaxIntegrationPurchTableDataRetrieval_Extension.xpp

[ExtensionOf(classStr(TaxIntegrationPurchTableDataRetrieval))]
final class TaxIntegrationPurchTableDataRetrieval_Extension
{
    private const str CostCenterKey = 'CostCenter';
    private const str ProjectKey = 'Project';

    /// <summary>
    /// Copies to the current line of the document from.
    /// </summary>
    /// <param name = "_line">The current line of the document.</param>
    protected void copyToLineFromLineTable(TaxIntegrationLineObject _line)
    {
        Map dimensionAttributeMap = this.getDimensionAttributeMapByDefaultDimension(this.purchline.DefaultDimension);
        if (dimensionAttributeMap.exists(CostCenterKey))
        {
            _line.setCostCenter(dimensionAttributeMap.lookup(CostCenterKey));
        }
        if (dimensionAttributeMap.exists(ProjectKey))
        {
            _line.setProjectId(dimensionAttributeMap.lookup(ProjectKey));
        }
        next copyToLineFromLineTable(_line);
    }
    private Map getDimensionAttributeMapByDefaultDimension(RefRecId _defaultDimension)
    {
        DimensionAttribute dimensionAttribute;
        DimensionAttributeValue dimensionAttributeValue;
        DimensionAttributeValueSetItem dimensionAttributeValueSetItem;
        Map ret = new Map(Types::String, Types::String);
        select Name, RecId from dimensionAttribute
            join dimensionAttributeValue
                where dimensionAttributeValue.dimensionAttribute == dimensionAttribute.RecId
            join DimensionAttributeValueSetItem
                where DimensionAttributeValueSetItem.DimensionAttributeValue == DimensionAttributeValue.RecId
                    && DimensionAttributeValueSetItem.DimensionAttributeValueSet == _defaultDimension;
        while(dimensionAttribute.RecId)
        {
            ret.insert(dimensionAttribute.Name, dimensionAttributeValue.DisplayValue);
            next dimensionAttribute;
        }
        return ret;
    }
}

TaxIntegrationCalculationActivityOnDocument_CalculationService_Extension.xpp

[ExtensionOf(classStr(TaxIntegrationCalculationActivityOnDocument_CalculationService))]
final static class TaxIntegrationCalculationActivityOnDocument_CalculationService_Extension
{
    // Define the field name in the request
    private const str IOCostCenter = 'Cost Center';
    private const str IOProject = 'Project';

    /// <summary>
    /// Copies to <c>TaxableDocumentLineWrapper</c> from <c>TaxIntegrationLineObject</c> by line.
    /// </summary>
    /// <param name = "_destination"><c>TaxableDocumentLineWrapper</c>.</param>
    /// <param name = "_source"><c>TaxIntegrationLineObject</c>.</param>
    protected static void copyToTaxableDocumentLineWrapperFromTaxIntegrationLineObjectByLine(Microsoft.Dynamics.TaxCalculation.ApiContracts.TaxableDocumentLineWrapper _destination, TaxIntegrationLineObject _source)
    {
        next copyToTaxableDocumentLineWrapperFromTaxIntegrationLineObjectByLine(_destination, _source);
        // Set the field we need to integrated for tax service
        _destination.SetField(IOCostCenter, _source.getCostCenter());
        _destination.SetField(IOProject, _source.getProjectId());
    }
}