Skip to main content

My Requirements: (Doing this for learning purpose)

An integration between an employee management web app and Acumatica ERP, just need to push the salary payment data to the ERP.

My Current Approach:

I have created a DAC called EmloymentHeroRawData which stores the raw data received from the employee management web app. I have created the web service endpoint and it works as expected. Now I need to create journal transaction entry, it should include the all transaction entries in the EmloymentHeroRawData DAC, excluding the already process rows. That part also works in my code.
after entering a row to a journal transaction entry I need to change the its status in to “COM”. But that part is not working.

When doing debugging I create a separate action called ToggleStatus just to change the status of all recode. But it also not works it gives following error.


Error: An attempt of an update of the whole table EmloymentHeroRawData was detected because of missed key values.

Code :
 

namespace Fruitspotv1

{

    public class EmploymentHeroRawDataGraph : PXGraph<EmploymentHeroRawDataGraph, EmloymentHeroRawData>

    {



        public PXSave<EmloymentHeroRawData> Save;

        public PXCancel<EmloymentHeroRawData> Cancel;



        public SelectFrom<EmloymentHeroRawData>.View EmloymentHeroRawDataView;




        #region Actions

        public PXAction<EmloymentHeroRawData> CreateGLAction;

        GPXProcessButton]

        rPXUIField(DisplayName = "Create GL", Enabled = true)]

        protected virtual IEnumerable createGLAction(PXAdapter adapter)

        {

            // Populate a local list variable.

            bool isMassProcess = adapter.MassProcess;

            List<EmloymentHeroRawData> list = new List<EmloymentHeroRawData>();

            foreach (EmloymentHeroRawData order in adapter.Get<EmloymentHeroRawData>())

            {

                list.Add(order);

            }

            Save.Press();

            PXLongOperation.StartOperation(this, delegate ()

            {

                ValidatePrices(list, isMassProcess);

            });

            return list;

        }

        #endregion



        #region Actions

        public PXAction<EmloymentHeroRawData> toggleStatus;

        PXProcessButton]

        tPXUIField(DisplayName = "Toggle Status", Enabled = true)]

        protected virtual IEnumerable ToggleStatus(PXAdapter adapter)

        {

            var emHero = CreateInstance<EmploymentHeroRawDataGraph>();

            var tranacationList = emHero.EmloymentHeroRawDataView.Select();




            foreach (EmloymentHeroRawData entitiy in tranacationList)

            {

                try

                {

                    entitiy.Status = "COM";

                }

                catch (Exception ex)

                {

                    entitiy.Status = "FIL";

                }

                emHero.EmloymentHeroRawDataView.Cache.Update(entitiy);

            }



            emHero.Actions.PressSave();

            // Save.Press();



            return tranacationList;

        }

        #endregion



        private static void ValidatePrices(List<EmloymentHeroRawData> emloymentHeroEntitiyList, bool isMassProcess = false)

        {

            try

            {

                using (var ts = new PXTransactionScope())

                {

                    var journalEntry = CreateInstance<JournalEntry>();

                    var doc = new Batch()

                    {

                        Module = "GL"

                    };

                    doc = journalEntry.BatchModule.Insert(doc);

                    Branch branch = PXSelect<Branch, Where<Branch.branchCD, Equal<Required<Branch.branchCD>>>>.Select(journalEntry, "HEADOFFICE");

                    EmploymentHeroRawDataGraph employmentHeroRawDataGraph = CreateInstance<EmploymentHeroRawDataGraph>();

                    //doc.LedgerCD = "ACTUAL";

                    doc.BranchID = branch.BranchID;

                    doc.Description = emloymentHeroEntitiyList.Count.ToString() + " Generated from EM";

                    journalEntry.BatchModule.Update(doc);




                    foreach (EmloymentHeroRawData entitiy in emloymentHeroEntitiyList)

                    {

                        Account account = PXSelect<Account, Where<Account.accountCD, Equal<Required<Account.accountCD>>>>.Select(journalEntry, entitiy.AccountCode);




                        try

                        {

                            var tr = new GLTran

                            {

                                AccountID = account.AccountID,

                                CuryCreditAmt = entitiy.Credit,

                                CuryDebitAmt = entitiy.Debit,



                            };

                            var tran = journalEntry.GLTranModuleBatNbr.Insert(tr);

                            //var savedData = journalEntry.GLTranModuleBatNbr.Update(tran);

                            entitiy.Status = "COM";

                        }

                        catch(Exception ex)

                        {

                            entitiy.Status = "FIL";

                        }

                    }

                   

                    // Trigger the Save action to save changes in the database.

                    journalEntry.Actions.PressSave();

                    ts.Complete();



                    if (isMassProcess)

                    {

                        //PXProcessing<EmloymentHeroRawData>.SetInfo(i,string.Format(Messages.WorkOrderAssigned,workOrder.OrderNbr));

                    }

                }

            }

            catch (Exception ex)

            {



            }

        }

    }

}

 

Have you tried this?

    try
{
var tr = new GLTran
{
AccountID = account.AccountID,
CuryCreditAmt = entitiy.Credit,
CuryDebitAmt = entitiy.Debit,
};

var tran = journalEntry.GLTranModuleBatNbr.Insert(tr);

//var savedData = journalEntry.GLTranModuleBatNbr.Update(tran);

entitiy.Status = "COM";

//*** try this?
employmentHeroRawDataGraph.EmloymentHeroRawDataView.Update(entitiy);
employmentHeroRawDataGraph.Persist();
}
catch(Exception ex)
{
entitiy.Status = "FIL";

//*** try this?
employmentHeroRawDataGraph.EmloymentHeroRawDataView.Update(entitiy);
employmentHeroRawDataGraph.Persist();
}
}

 


@darylbowman thank you for the support. I tried this.
when add these lines, did not create the journal transaction entry. but in the process screen it shows as successfully process. still throws the following exception “An attempt of an update of the whole table EmloymentHeroRawData was detected because of missed key values.”
 


@darylbowman when comment the code line inside the catch block it works.
 

foreach (EmloymentHeroRawData entitiy in tranacationList)
{
Account account = PXSelect<Account, Where<Account.accountCD, Equal<Required<Account.accountCD>>>>.Select(journalEntry, entitiy.AccountCode);

try
{
var tr = new GLTran
{
AccountID = account.AccountID,
CuryCreditAmt = entitiy.Credit,
CuryDebitAmt = entitiy.Debit,

};

var savedData = journalEntry.GLTranModuleBatNbr.Update(tr);
entitiy.Status = "C01";
emHero.EmloymentHeroRawDataView.Update(entitiy);
emHero.Persist();

}
catch (Exception ex)
{
entitiy.Status = "F01";
//emHero.EmloymentHeroRawDataView.Update(entitiy);
//emHero.Persist();
}
}

 


Could you post the DAC for EmloymentHeroRawData?


using System;
using PX.Data;

namespace Fruitspotv1
{
[Serializable]
[PXCacheName("EmloymentHeroRawData")]
public class EmloymentHeroRawData : IBqlTable
{
#region RefNbr
[PXDBString(32, IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Ref Nbr")]
public virtual string RefNbr { get; set; }
public abstract class refNbr : PX.Data.BQL.BqlString.Field<refNbr> { }
#endregion

#region AccountCode
[PXDBString(32, IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Account Code")]
public virtual string AccountCode { get; set; }
public abstract class accountCode : PX.Data.BQL.BqlString.Field<accountCode> { }
#endregion

#region SubAccountCode
[PXDBString(32, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Sub Account Code")]
public virtual string SubAccountCode { get; set; }
public abstract class subAccountCode : PX.Data.BQL.BqlString.Field<subAccountCode> { }
#endregion

#region Debit
[PXDBDecimal(IsKey = true)]
[PXUIField(DisplayName = "Debit")]
public virtual Decimal? Debit { get; set; }
public abstract class debit : PX.Data.BQL.BqlDecimal.Field<debit> { }
#endregion

#region DebitTax
[PXDBDecimal()]
[PXUIField(DisplayName = "Debit Tax")]
public virtual Decimal? DebitTax { get; set; }
public abstract class debitTax : PX.Data.BQL.BqlDecimal.Field<debitTax> { }
#endregion

#region Credit
[PXDBDecimal(IsKey = true)]
[PXUIField(DisplayName = "Credit")]
public virtual Decimal? Credit { get; set; }
public abstract class credit : PX.Data.BQL.BqlDecimal.Field<credit> { }
#endregion

#region CreditTax
[PXDBDecimal()]
[PXUIField(DisplayName = "Credit Tax")]
public virtual Decimal? CreditTax { get; set; }
public abstract class creditTax : PX.Data.BQL.BqlDecimal.Field<creditTax> { }
#endregion

#region Reference
[PXDBString(1024, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Reference")]
public virtual string Reference { get; set; }
public abstract class reference : PX.Data.BQL.BqlString.Field<reference> { }
#endregion

#region Location
[PXDBString(512, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Location")]
public virtual string Location { get; set; }
public abstract class location : PX.Data.BQL.BqlString.Field<location> { }
#endregion

#region Task
[PXDBString(255, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Task")]
public virtual string Task { get; set; }
public abstract class task : PX.Data.BQL.BqlString.Field<task> { }
#endregion

#region TaxCode
[PXDBString(32, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Tax Code")]
public virtual string TaxCode { get; set; }
public abstract class taxCode : PX.Data.BQL.BqlString.Field<taxCode> { }
#endregion

#region Active
[PXDBBool()]
[PXUIField(DisplayName = "Active")]
[PXDefault(true)]
public virtual bool? Active { get; set; }
public abstract class active : PX.Data.BQL.BqlBool.Field<active> { }
#endregion

#region Status
[PXDBString(3)]
[PXUIField(DisplayName = "Status")]
[PXDefault("RAW")]
public virtual string Status { get; set; }
public abstract class status : PX.Data.BQL.BqlString.Field<status> { }
#endregion

#region Selected
public abstract class selected : PX.Data.BQL.BqlBool.Field<selected> { }
[PXBool]
[PXUIField(DisplayName = "Selected")]
public virtual bool? Selected { get; set; }
#endregion

#region CreatedDateTime
[PXDBCreatedDateTime()]
public virtual DateTime? CreatedDateTime { get; set; }
public abstract class createdDateTime : PX.Data.BQL.BqlDateTime.Field<createdDateTime> { }
#endregion

#region CreatedByID
[PXDBCreatedByID()]
public virtual Guid? CreatedByID { get; set; }
public abstract class createdByID : PX.Data.BQL.BqlGuid.Field<createdByID> { }
#endregion

#region CreatedByScreenID
[PXDBCreatedByScreenID()]
public virtual string CreatedByScreenID { get; set; }
public abstract class createdByScreenID : PX.Data.BQL.BqlString.Field<createdByScreenID> { }
#endregion

#region LastModifiedDateTime
[PXDBLastModifiedDateTime()]
public virtual DateTime? LastModifiedDateTime { get; set; }
public abstract class lastModifiedDateTime : PX.Data.BQL.BqlDateTime.Field<lastModifiedDateTime> { }
#endregion

#region LastModifiedByID
[PXDBLastModifiedByID()]
public virtual Guid? LastModifiedByID { get; set; }
public abstract class lastModifiedByID : PX.Data.BQL.BqlGuid.Field<lastModifiedByID> { }
#endregion

#region LastModifiedByScreenID
[PXDBLastModifiedByScreenID()]
public virtual string LastModifiedByScreenID { get; set; }
public abstract class lastModifiedByScreenID : PX.Data.BQL.BqlString.Field<lastModifiedByScreenID> { }
#endregion

#region Tstamp
[PXDBTimestamp()]
[PXUIField(DisplayName = "Tstamp")]
public virtual byte[] Tstamp { get; set; }
public abstract class tstamp : PX.Data.BQL.BqlByteArray.Field<tstamp> { }
#endregion

#region Noteid
[PXNote()]
public virtual Guid? Noteid { get; set; }
public abstract class noteid : PX.Data.BQL.BqlGuid.Field<noteid> { }

public class preliminaryCheck
{
}
#endregion
}
}

Hi @darylbowman this is my custom DAC.


What's the logic for including 'Debit' and 'Credit' as keys for the table?


@darylbowman this DAC is used to store raw data which are fetched from separate 3rd party application. it did not contain a unique identifier for each recode. The field “RefNbr” is supposed to store an auto generated key. I used it for make easier the data handling. But to avoid the data redundancy I supposed to make Debit, Credit, AccountCode and Status fields as keys, but mistakenly Status is still not marked as a key,


It would seem like something is misconfigured with your keys. Make sure your DAC fields marked as keys correspond to your database table keys.


@darylbowman Okay, I will try that.

 


@darylbowman I change the Key fields in the DAC, then it works fine. Thank you for your great support.


Reply