Payment not being created - c#

My payments are not showing up in QuickBooks.
I can successfully create and update Customers. I can also successfully create and update Invoices. I cannot create Payments. But here's the thing, when I execute the Update command on my Payment object I do get a proper Id and Domain (NG) passed back. I've checked the Sync log file (IntuitSyncManagerLogger.log) after running a Sync but it has no error messages. Everything looks ok, there just is no payment associated with the invoice in QuickBooks.
I believe I'm setting all of the required fields but I'm not sure about two of them.
1) The PaymentLine has a field named TxnId. I'm setting it to be the Id and Domain of the InvoiceHeader, but am not sure if this is correct.
2) There is another required field (per the documentation) but I'm leaving it blank as I don't know what to populate it with. It's the DiscountAccountId field. I don't want a discount associated with the invoice.
Here is my code...
SqlConnection connection = new SqlConnection(m_connectionString);
connection.Open();
SqlCommand cmd = new SqlCommand("dbo.Intuit_GetPayment", connection);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#glmvSyncId", SqlDbType.Int).Value = glmvSyncId;
SqlDataReader rdr = cmd.ExecuteReader();
rdr.Read();
Intuit.Ipp.Data.Qbd.PaymentHeader paymentHeader = new Intuit.Ipp.Data.Qbd.PaymentHeader();
paymentHeader.ARAccountId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = Intuit.Ipp.Data.Qbd.idDomainEnum.QB,
Value = "37"
};
paymentHeader.ARAccountName = "Accounts Receivable";
paymentHeader.DepositToAccountId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = Intuit.Ipp.Data.Qbd.idDomainEnum.QB,
Value = "35"
};
paymentHeader.DepositToAccountName = "Undeposited Funds";
paymentHeader.CustomerId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = (rdr["cust_iddomain"].ToString() == "QB" ? Intuit.Ipp.Data.Qbd.idDomainEnum.QB : Intuit.Ipp.Data.Qbd.idDomainEnum.NG),
Value = rdr["cust_idvalue"].ToString()
}; // cust_iddomain and cust_idvalue are from the Customer
paymentHeader.DocNumber = rdr["invoicekey"].ToString();
paymentHeader.TxnDate = DateTime.Now;
List<Intuit.Ipp.Data.Qbd.PaymentLine> listLine = new List<Intuit.Ipp.Data.Qbd.PaymentLine>();
var paymentLine = new Intuit.Ipp.Data.Qbd.PaymentLine();
paymentLine.Amount = Convert.ToDecimal(rdr["amount"]);
paymentLine.TxnId = new Intuit.Ipp.Data.Qbd.IdType() {
idDomain = (rdr["invc_iddomain"].ToString() == "QB" ? Intuit.Ipp.Data.Qbd.idDomainEnum.QB : Intuit.Ipp.Data.Qbd.idDomainEnum.NG),
Value = rdr["invc_idvalue"].ToString()
}; // invc_iddomain and invc_idvalue are from the InvoiceHeader
listLine.Add(paymentLine);
Intuit.Ipp.Data.Qbd.Payment syncPayment = new Intuit.Ipp.Data.Qbd.Payment();
syncPayment.Header = paymentHeader;
syncPayment.Line = listLine.ToArray();
connection.Close();
Intuit.Ipp.Data.Qbd.Payment resultPayment = new Intuit.Ipp.Data.Qbd.Payment();
resultPayment = commonService.Add(syncPayment);
I suspect the problem is with TxnId.
All I'm doing is creating a Customer, then creating an Invoice for the Customer, then creating a Payment for the Invoice. Am I missing a object someplace?
Any and all help is greatly appreciated.

The Payment is likely going into an error state after sync. You can check by executing a PaymentQuery and setting ErroredObjectsOnly=true.
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0100_Calling_Data_Services/0015_Retrieving_Objects#Objects_in_Error_State
If the entity is in error state, you can query for the specific reason using the Status API:
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0600_Object_Reference/SyncStatus
SyncStatusRequest syncStatusRequest = new SyncStatusRequest();
syncStatusRequest.ErroredObjectsOnly = true;
syncStatusRequest.NgIdSet = new NgIdSet[] { new NgIdSet { NgId = <<EnterYourNgIdHere>>, NgObjectType = objectName.Payment } };
SyncStatusResponse[] response = dataServices.GetSyncStatus(syncStatusRequest);
If the payment is in error state, you can delete the entity from the cloud since it was never synced with QuickBooks:
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0100_Calling_Data_Services/Deleting_an_Object
If a successful sync did occur with the entity at least once, but then an Update pushed it into error state, you will need to do a Revert:
https://ipp.developer.intuit.com/0010_Intuit_Partner_Platform/0050_Data_Services/0500_QuickBooks_Windows/0100_Calling_Data_Services/Reverting_an_Object
You can also try doing an Update directly on the entity in error state once you know the reason from the Status API, but it is not documented so it may not work.

Adding the following lines of code seems to have fixed the problem. The Payment is now being recorded in QuickBooks.
paymentHeader.TotalAmt = Convert.ToDecimal(rdr["amount"]);
paymentHeader.TotalAmtSpecified = true;

Related

How to create New EPT by using CSOM

I try to create a new EPT (project server 2013) using C# CSOM library.
But It has following error occurred.
"PJClientCallableException: EnterpriseProjectTypeInvalidCreatePDPUid"
Couple of article tell to change the "IsCreate=true". But it does not success for me. Here is the code what I have done.
public void CreateEnterpriseProjectType(Guid eptGuid, string eptName, string eptDescription)
{
ProjectContext pwaContext = new ProjectContext(this.PWA_URL);
EnterpriseProjectTypeCreationInformation eptData = new EnterpriseProjectTypeCreationInformation();
eptData.Id = eptGuid;
eptData.Name = eptName;
eptData.Description = eptDescription;
eptData.IsDefault = false;
eptData.IsManaged = true;
eptData.WorkspaceTemplateName = "PROJECTSITE#0";
eptData.ProjectPlanTemplateId = Guid.Empty;
eptData.WorkflowAssociationId = Guid.Empty;
eptData.Order = 4;
List<ProjectDetailPageCreationInformation> projectDetailPages = new
List<ProjectDetailPageCreationInformation>() {
new ProjectDetailPageCreationInformation() {
Id = pwaContext.ProjectDetailPages[1].Id, IsCreate = true }
};
eptData.ProjectDetailPages = projectDetailPages;
pwaContext.Load(pwaContext.EnterpriseProjectTypes);
pwaContext.ExecuteQuery();
EnterpriseProjectType newEpt = pwaContext.EnterpriseProjectTypes.Add(eptData);
pwaContext.EnterpriseProjectTypes.Update();
pwaContext.ExecuteQuery();
}
Can anyone explain the issue or provide the working code part.
I would like to suggest the following:
Define an enterprise project type:
string basicEpt = "Enterprise Project"; // Basic enterprise project type.
int timeoutSeconds = 10; // The maximum wait time for a queue job, in seconds.
And then, when you create the new project, work like this:
ProjectCreationInformation newProj = new ProjectCreationInformation();
newProj.Id = Guid.NewGuid();
newProj.Name = "Project Name";
newProj.Description = "Test creating a project with CSOM";
newProj.Start = DateTime.Today.Date;
// Setting the EPT GUID is optional. If no EPT is specified, Project Server
// uses the default EPT.
newProj.EnterpriseProjectTypeId = GetEptUid(basicEpt);
PublishedProject newPublishedProj = projContext.Projects.Add(newProj);
QueueJob qJob = projContext.Projects.Update();
// Calling Load and ExecuteQuery for the queue job is optional.
// projContext.Load(qJob);
// projContext.ExecuteQuery();
JobState jobState = projContext.WaitForQueue(qJob, timeoutSeconds);
When the last line of that piece of code ends, the project must be created and published in order to define tasks or whatever.
I don't know what is happening to your code, seems great.
Hope it helps to you,

Error throw exception when insert data with thread

I have probem when use thread in winform.
I have error when debug program.
My Application throw exception when start program.
I define class RunInUIThread is:
private void RunInUIThread(Delegate method)
{
this.BeginInvoke(method);
}
And in RunInUIThread method like:
BaiXeBUS baixe = new BaiXeBUS();
RunInUIThread(new ThreadStart(delegate ()
{
BaiXeDTO obj = new BaiXeDTO(); //Map all to define database
txtKhuVucBai.Text = mReader.CurrentCardIDBlock1.ToString();
txtMaThe.Text = mReader.CurrentCardIDBlock2.ToString();
//If I comment all below code. It's work. But I need Insert data to database.
txtKhuVucBai.Text = obj.IDBaiXe.ToString();
txtMaThe.Text = obj.IDRF.ToString();
obj.BienSoXe = textBox1.Text;
obj.HinhBienSo = color.ToString();
obj.HinhChuXe = img.ToString();
obj.ThoiGianVao = DateTime.Now.ToLocalTime();
obj.ThoiGianRa = DateTime.Now.ToLocalTime();
baixe.BaiXe_Insert(obj); //Contain data access layer to insert data with store procedure.
}));
Why my code not work. Someone can explain me and how to fix problem?
Thank all reader!!!
What I mean is trying to run this block of code without the ThreadStart
{
BaiXeDTO obj = new BaiXeDTO(); //Map all to define database
txtKhuVucBai.Text = mReader.CurrentCardIDBlock1.ToString();
txtMaThe.Text = mReader.CurrentCardIDBlock2.ToString();
//If I comment all below code. It's work. But I need Insert data to database.
txtKhuVucBai.Text = obj.IDBaiXe.ToString();
txtMaThe.Text = obj.IDRF.ToString();
obj.BienSoXe = textBox1.Text;
obj.HinhBienSo = color.ToString();
obj.HinhChuXe = img.ToString();
obj.ThoiGianVao = DateTime.Now.ToLocalTime();
obj.ThoiGianRa = DateTime.Now.ToLocalTime();
baixe.BaiXe_Insert(obj); //Contain data access layer to insert data with store procedure.
}
This is to debug your code within the main thread.
#JoelLegaspiEnriquez, your recommned me to remove [STAThread] in Program.cs?
If I comment this line. This have problem in control AxLiveX1 is control of camera ip.
The txtKhuVucBai.Text = mReader.CurrentCardIDBlock1.ToString(); is Guid type with 16byte: 8d58d690-6b71-4ee8-85ad-006db0287bf1.
But i assign txtKhuVucBai to Guid type is:
private Guid mCurrentCardIDBlock1;
public Guid CurrentCardIDBlock1
{
get { return mCurrentCardIDBlock1; }
}
The mCurrentCardIDBlock1 is type of RFID reader with 32 character random.

How to update an existing exchange rate

Using the ExchangeRateServiceClient every time I try to use client.create for currency a currency code pair I get an exception
Cannot create a record in Exchange rate currency pair (ExchangeRateCurrencyPair). From currency: USD, EUR. The record already exists.
System.Exception {System.ServiceModel.FaultException}
I am brand new to the AX API...I am using C#
AXDev09.ExchangeRateServiceCreateRequest request =
new AXDev09.ExchangeRateServiceCreateRequest();
AXDev09.ExchangeRateServiceClient client = new AXDev09.ExchangeRateServiceClient();
request.CallContext = new AXDev09.CallContext();
request.CallContext.Language = "en-us";
request.CallContext.Company = "T51";
request.CallContext.MessageId = Guid.NewGuid().ToString();
AXDev09.AxdEntity_CurrencyPair[] myPair = new AXDev09.AxdEntity_CurrencyPair[1];
myPair[0] = new AXDev09.AxdEntity_CurrencyPair();
myPair[0].ToCurrencyCode = "EUR";
myPair[0].FromCurrencyCode = "USD";
AXDev09.AxdEntity_ExchangeRate[] myExchange = new AXDev09.AxdEntity_ExchangeRate[1];
myExchange[0] = new AXDev09.AxdEntity_ExchangeRate();
myExchange[0].ExchangeRate = Convert.ToDecimal("0.708");
myExchange[0].ExchangeRateSpecified = true;
myPair[0].ExchangeRate = myExchange;
myPair[0].ExchangeRateDisplayFactor = AXDev09.AxdEnum_ExchangeRateDisplayFactor.One;
myPair[0].ExchangeRateType = "Average";
AxdType_DateTime myFromDate = new AxdType_DateTime();
myFromDate.localDateTime = DateTime.Now.ToUniversalTime();
myFromDate.timezone = AxdEnum_Timezone.GMTMINUS0600CENTRALTIME;
myFromDate.Value = myFromDate.localDateTime;
AxdType_DateTime myToDate = new AxdType_DateTime();
myToDate.localDateTime = DateTime.Now.ToUniversalTime();
myToDate.timezone = AxdEnum_Timezone.GMTMINUS0600CENTRALTIME;
myToDate.Value = myToDate.localDateTime;
request.LedgerExchangeRate = new AXDev09.AxdLedgerExchangeRate();
request.LedgerExchangeRate.CurrencyPair = myPair;
request.LedgerExchangeRate.ValidFromDateTime = myFromDate;
request.LedgerExchangeRate.ValidToDateTime = myToDate;
client.Open();
client.create(request.CallContext, request.LedgerExchangeRate);
client.Close();
The ExchangeRateServiceClient does appear to be a standard API.
The standards web service is called LedgerExchangeRateService.
If you provide two currencies, then try to reverse them.
if the error message is to be believed, seems like the issue is when it tries to create the ExchangeRateCurrencyPair
there is a no-duplicates index on:
fromCurrency
toCurrency
ExchangeRateType
"I am trying to add a new currency rate...with a new set from from-to but I keep getting "The record already exists" error eventhough I'm setting new FROM-TO dates."
it seems to be objecting to ExchangeRateCurrencyPair(not to the date effective bits) maybe try selecting the pair instead of attempting to create it every time--or maybe try debugging through a successful new pair to see if a tweak may be needed in the standard service

Silverlight -CRM2011 : The Currency Cannot Be null

I use Silverlight o-data services to interact with crm 2011 from my application
When I try to save the data in the entity SalesOrder as follows:
Private void beginSave()
{
SalesOrder orderHeader = new SalesOrder();
orderHeader.TransactionCurrencyId = new EntityReference(){ Id = new Guid("77D695B5-ACB4-E111-97BC-00155D55B216"), LogicalName="transactioncurrency" };
orderHeader.AccountId = new EntityReference() { Id = new Guid(MyClassGeneralOrder.customerId), LogicalName = "account" };
orderHeader.Name = "My Name";
Money totalAmount = new Money(); Money totalAmountBase = new Money();
Money totalTaxe = new Money(); Money totalAmountLessFreight = new Money();
totalAmount.Value = (decimal)MyClassGeneralOrder.InvoiceTotal;
totalAmountBase.Value = (decimal)MyClassGeneralOrder.totalRetail;
totalTaxe.Value = (decimal)MyClassGeneralOrder.totalCharges;
totalAmountLessFreight.Value = (decimal)MyClassGeneralOrder.totalNet;
orderHeader.TotalAmount = totalAmount;
orderHeader.TotalAmount_Base = totalAmountBase;
orderHeader.TotalTax = totalTaxe;
orderHeader.TotalAmountLessFreight = totalAmountLessFreight;
orderHeader.Description = element.Name;
orderHeader.PriceLevelId = new EntityReference() { Id = new Guid("03C5C4CB-EBD0-E111-8140-00155D55B216"), LogicalName="pricelevel" };
_context.AddToSalesOrderSet(orderHeader);
_context.BeginSaveChanges(SaveCallback, orderHeader);
}
private void SaveCallback(IAsyncResult result)
{
_context.EndSaveChanges(result);
}
In my function EndSaveChanges (result), I receive this error message : : « The Currency Cannot Be null ».
I don't understand why, because my "orderHeader.TransactionCurrencyId" field is not null.
I assuming that all of your other Currency fields are populated?
Any chance you have another plugin that is firing as a result of yours that is throwing the exception. That always seems to bite me. Try disabling all other plugins except for the one you're working on...
If you're still having issues, turn on crm server side tracing. You'll get much better error information. Use the CRM diagnostic tool to turn on trace logging: http://crmdiagtool2011.codeplex.com
Mostly your Guid is wrong and it's resulting in null. Make sure it's the correct GUID you are using or not. Run an advanced find against the entity and find the correct GUID. It's not a good idea to hard code the GUID. If you deploy your solutions to some other org it won't work.

linq to sql one-one relationship C#

It is necessary that after the creation of records in the table "Clients" took up ID. Later ID used to create a new entry in the "Clients_details".
var user = GetUsers();
var userdet = GetclientsDetails();
string hashedpass = getMd5Hash(UIPassword.Text);
var newreg = new Clients
{
login = UILogin.Text,
password = hashedpass,
subscribeid = Convert.ToInt32(UIId.Text)
};
user.InsertOnSubmit(newreg);
user.Context.SubmitChanges();
var details = new Clients_details
{
city = UICity.Text,
first_name = UIFirst_name.Text,
last_name = UIFamiliya.Text,
name = UIName.Text,
Clients = newreg
};
userdet.InsertOnSubmit(details);
userdet.Context.SubmitChanges();
After this code fails:
"An attempt was made to perform an operation Attach or Add in relation to an object that is not new, and possibly loaded from another DataContext. This operation is not supported."
How to properly create a record that does not appear a mistake? Thank you!
private static Table<Clients> GetUsers()
{
var dce = new BaseDBMLDataContext();
return dce.Clients;
}
private static Table<Clients_details> GetclientsDetails()
{
var dce = new BaseDBMLDataContext();
return dce.Clients_details;
}
Looks like userdet.Context and user.Context was built using a different dataContext and that needs to be created using the same dataContext rather than instantiating a new one.
I think you need to only call the SubmitChanges only once in the end, and also you need to make sure the user and userdet you are using share the same context
As the error clearly states, you're using different contexts (user and userdet) for each entity to add. You should have one DataContext and use that one to add the entities.
Yes looks like you're using two different instances of the same context:
user.Context.SubmitChanges();
userdet.Context.SubmitChanges();
A good approach to build up your entities should be something like :
//Create your client details entity
var details = new Clients_details
{
city = UICity.Text,
first_name = UIFirst_name.Text,
last_name = UIFamiliya.Text,
name = UIName.Text
};
//Create your client entity
var newreg = new Clients
{
login = UILogin.Text,
password = hashedpass,
subscribeid = Convert.ToInt32(UIId.Text),
//Assigning the details entity (FK) to the client
ClientDetails = details
};
//Saving both the client and its details
user.InsertOnSubmit(newreg);
user.Context.SubmitChanges();

Categories