How to hide a field while copy and past. The field is part of the extension of the sales order.DAC.
I have tried [PXCopyPasteHiddenFields(typeof(PSSOOrderExtNV.usrIsInHandsDate))] and I am getting the following compilation error.
Error CS0592 Attribute 'PXCopyPasteHiddenFields' is not valid on this declaration type. It is only valid on 'class, field' declarations.
I have tried to Override the method CopyPasteGetScript I did not get the desired result.
public delegate void CopyPasteGetScriptDelegate(Boolean isImportSimple, List<Command> script, List<Container> containers);
[PXOverride]
public void CopyPasteGetScript(Boolean isImportSimple, List<Command> script, List<Container> containers, CopyPasteGetScriptDelegate baseMethod)
{
baseMethod(isImportSimple, script, containers);
SOOrder order = Base.Document.Current;
if(Base.Document.Cache.GetStatus(order) == PXEntryStatus.Inserted)
{
PSSOOrderExtNV extn = PXCache<SOOrder>.GetExtension<PSSOOrderExtNV>(order);
extn.UsrHoldUntil = null;
extn.UsrReadyforProductionapproval = null;
extn.UsrReadyForProduction = null;
extn.UsrIsOrdered = null;
extn.UsrIsAllocated = null;
extn.UsrEmbPaperReceived = null;
extn.UsrEmbGoodsReceived = null;
extn.UsrWorksheetPrinted = null;
extn.UsrGoodsOnCarts = null;
Base.Document.Update(order);
}
}
Update
I have modified the code as bellow in graph extension of SOOrderEntry. It is not giving error while compiling, but it is copying the values to new order.
[PXCopyPasteHiddenFields(typeof(SOOrder.cancelled), typeof(SOOrder.preAuthTranNumber), typeof(SOOrder.ownerID), typeof(SOOrder.workgroupID),
typeof(PSSOOrderExtNV.usrHoldUntil),typeof(PSSOOrderExtNV.usrReadyForProduction),typeof(PSSOOrderExtNV.usrReadyforProductionapproval),typeof(PSSOOrderExtNV.usrIsOrdered),
typeof(PSSOOrderExtNV.usrIsAllocated),typeof(PSSOOrderExtNV.usrEmbPaperReceived),typeof(PSSOOrderExtNV.usrEmbGoodsReceived),typeof(PSSOOrderExtNV.usrWorksheetPrinted),
typeof(PSSOOrderExtNV.usrGoodsOnCarts))]
public PXSelect<SOOrder, Where<SOOrder.orderType, Equal<Current<SOOrder.orderType>>, And<SOOrder.orderNbr, Equal<Current<SOOrder.orderNbr>>>>> CurrentDocument;
PXCopyPasteHiddenFields attribute typically decorates DataViews.
This example in Sales Order graph, hides the SOLine.Completed field from the Transactions DataView:
[PXViewName(Messages.SOLine)]
[PXImport(typeof(SOOrder))]
[PXCopyPasteHiddenFields(typeof(SOLine.completed))]
public PXOrderedSelect<SOOrder, SOLine,
Where<SOLine.orderType, Equal<Current<SOOrder.orderType>>,
And<SOLine.orderNbr, Equal<Current<SOOrder.orderNbr>>>>,
OrderBy<Asc<SOLine.orderType, Asc<SOLine.orderNbr, Asc<SOLine.sortOrder, Asc<SOLine.lineNbr>>>>>> Transactions;
Related
I'm successfully redirecting to a Dashboard passing parameter from Customers screen (AR303000) but, not able to replicate the result when I redirect to the Dashboard from Customer Pop Up Panel. it call the Dashboard without the parameter. I can see the code passing the value correctly, but the Dashboard does not display any value.
Any Help will be appreciated.
Thanks.
Alfredo
Here is a copy of the code.
#region CustomerCard
public PXAction<PX.Objects.AR.Customer> customerCard;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Customer Card")]
protected void CustomerCard()
{
Customer customer = Base.BAccount.Current;
if (customer != null)
{
string screenID = "DBPS0007"; //DashboardID
PXSiteMapNode sm = GIScreenHelper.GetSiteMapNode(screenID);
PXGraph graph = GIScreenHelper.InstantiateGraph(screenID);
if (graph is LayoutMaint)
{
LayoutMaint copygraph = graph as LayoutMaint;
Dictionary<string, object> parameters = new
Dictionary<string, object>();
parameters["CustomerAccountID"] = customer.AcctCD;
copygraph.Filter.Current.Values = parameters;
throw new PXRedirectRequiredException(sm.Url, copygraph,
PXBaseRedirectException.WindowMode.New, string.Empty);
}
}
}
#endregion
The goal is taking the Journal Transaction generated from the AP Bill page and adding 2 additional rows in GLTran.
1st Attempt
First, I extended the Release action from the Journal Transactions graph to include the 2 new lines:
public class JournalEntryExt : PXGraphExtension<JournalEntry>
{
public delegate IEnumerable ReleaseDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
baseMethod(adapter);
//new code
GLTran tranRow = new GLTran();
tranRow = this.Base.GLTranModuleBatNbr.Insert(tranRow);
tranRow.AccountID = 2713;
tranRow.SubID = 467;
tranRow.CuryDebitAmt = 100;
this.Base.GLTranModuleBatNbr.Update(tranRow);
tranRow = new GLTran();
tranRow = this.Base.GLTranModuleBatNbr.Insert(tranRow);
tranRow.AccountID = 1514;
tranRow.SubID = 467;
tranRow.CuryCreditAmt = 100;
this.Base.GLTranModuleBatNbr.Update(tranRow);
this.Base.Actions.PressSave();
return adapter.Get();
}
Result: Creating and releasing the batch, entered the 2 new lines correctly.
After this, I thought that releasing the AP Bill would also trigger this extended logic from the GL Page. However, that didn't occur - The release of the Bill doesn't seem to re-use the Release logic defined in the GL page.
2nd Attempt
Then, I went back to the GL page and included the logic in the RowPersisted event, so that the 2 new lines would get created right after saving the document:
public class JournalEntryExt : PXGraphExtension<JournalEntry>
{
protected virtual void Batch_RowPersisted(PXCache sender, PXRowPersistedEventArgs e)
{
if (e.Row == null)
{
return;
}
Batch batchRow = (Batch)e.Row;
if (batchRow != null
&& e.Operation == PXDBOperation.Insert
&& e.TranStatus == PXTranStatus.Completed)
{
////new code
GLTran tranRow = new GLTran();
tranRow = this.Base.GLTranModuleBatNbr.Insert(tranRow);
tranRow.AccountID = 2713;
tranRow.SubID = 467;
tranRow.CuryDebitAmt = 102;
this.Base.GLTranModuleBatNbr.Update(tranRow);
tranRow = new GLTran();
tranRow = this.Base.GLTranModuleBatNbr.Insert(tranRow);
tranRow.AccountID = 1514;
tranRow.SubID = 467;
tranRow.CuryCreditAmt = 102;
this.Base.GLTranModuleBatNbr.Update(tranRow);
}
}
Result: Creating and saving the Batch correctly entered the 2 new lines.
After this, I thought that releasing the AP Bill would trigger this extended event, given that a Journal Entry graph should get created and used from the Bill page, but in this case, also releasing the AP Bill, did not add the 2 new lines in the generated Batch.
3rd Attempt
Then I thought I could extend the Bill's Release action and take control of the generated Journal Entry with the Search<> method. However, in this case, the extended logic seems to be executed within a transaction as the Document.Current.BatchNbr was still NULL:
4th Attempt
Finally, I tried to extend the Persist() method of APReleaseProcess similarly to how it's done in the guide T300, however none of the methods are listed (version 17.207.0029):
Any other ideas as to how to enter these GL Lines?
Thanks!
Hopefully, it didn't take you forever to go through these 4 attempts... I've got to say though, the number of efforts and details in your question is quite impressive and definitely very appreciated!
A 2-step customization will be required to insert 2 additional GL Transactions in the Batch generated for an AP Bill:
to insert additional GL Transactions, you need to override Persist method within the JournalEntry BLC extension and invoke the logic to insert additional GLTrans only if the custom ModifyBatchFromAP boolean flag value equals True:
using PX.Data;
using System;
namespace PX.Objects.GL
{
public class JournalEntry_Extension : PXGraphExtension<JournalEntry>
{
private bool modifyBatchFromAP = false;
public bool ModifyBatchFromAP
{
get
{
return modifyBatchFromAP;
}
set
{
modifyBatchFromAP = value;
}
}
[PXOverride]
public void Persist(Action del)
{
if (ModifyBatchFromAP)
{
var glTran = Base.GLTranModuleBatNbr.Insert();
Base.GLTranModuleBatNbr.SetValueExt<GLTran.accountID>(glTran, "20000");
glTran = Base.GLTranModuleBatNbr.Update(glTran);
Base.GLTranModuleBatNbr.SetValueExt<GLTran.subID>(glTran, "000000");
glTran.CuryDebitAmt = 100;
glTran.TranDesc = "Additional Debit Transaction for AP Doc";
Base.GLTranModuleBatNbr.Update(glTran);
glTran = Base.GLTranModuleBatNbr.Insert();
Base.GLTranModuleBatNbr.SetValueExt<GLTran.accountID>(glTran, "20200");
glTran = Base.GLTranModuleBatNbr.Update(glTran);
Base.GLTranModuleBatNbr.SetValueExt<GLTran.subID>(glTran, "000000");
glTran.CuryCreditAmt = 100;
glTran.TranDesc = "Additional Credit Transaction for AP Doc";
Base.GLTranModuleBatNbr.Update(glTran);
}
del();
}
}
}
after that in the overridden Release action within the APInvoiceEntry_Extension, you will subscribe to the InstanceCreated event for the JournalEntry BLC type to set ModifyBatchFromAP flag value to True allowing your logic from step 1 to execute for the Batch generated only for an AP document:
using PX.Data;
using PX.Objects.GL;
using System.Collections;
namespace PX.Objects.AP
{
public class APInvoiceEntry_Extension : PXGraphExtension<APInvoiceEntry>
{
public delegate IEnumerable ReleaseDelegate(PXAdapter adapter);
[PXOverride]
public IEnumerable Release(PXAdapter adapter, ReleaseDelegate baseMethod)
{
PXGraph.InstanceCreated.AddHandler<JournalEntry>((JournalEntry graph) =>
{
graph.GetExtension<JournalEntry_Extension>().ModifyBatchFromAP = true;
});
return baseMethod(adapter);
}
}
}
P.S. it is not currently possible to use the Select Method to Override dialog with the APReleaseProcess class due to PXHiddenAttribute applied to it. Let me forward this to our Engineering Team to bring their attention on that matter.
I need help to update the value of Project's attribute from different page.
I have fetched the attribute value in 'Appointments' page using following code.
protected void FSAppointment_RowSelected(PXCache cache, PXRowSelectedEventArgs e, PXRowSelected InvokeBaseHandler)
{
if (InvokeBaseHandler != null)
InvokeBaseHandler(cache, e);
var row = (FSAppointment)e.Row;
AppointmentEntry graph = (AppointmentEntry)cache.Graph;
if (graph.ServiceOrderRelated.Current != null)
{
int? projectID = graph.ServiceOrderRelated.Current.ProjectID;
ProjectEntry projectGraph = PXGraph.CreateInstance<ProjectEntry>();
projectGraph.Project.Current = projectGraph.Project.Search<PMProject.contractID>(projectID);
foreach (CSAnswers att in projectGraph.Answers.Select())
{
if (att.AttributeID == "ESTHOURS")
{
cache.SetValueExt<FieldService.ServiceDispatch.FSAppointmentExt.usrProjectEstimatedRemainingHours>(row, att.Value);
return;
}
}
}
}
And, now I want user to be able to update that particular attribute's value from 'Appointments' page.
For that, I had written following code by overriding the Persist method of 'Appointments' page.
public delegate void PersistDelegate();
[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
if (Base.ServiceOrderRelated.Current != null)
{
using (PXTransactionScope scope = new PXTransactionScope())
{
int? projectID = Base.ServiceOrderRelated.Current.ProjectID;
ProjectEntry projectGraph = PXGraph.CreateInstance<ProjectEntry>();
var project = projectGraph.Project.Search<PMProject.contractID>(projectID);
var answers = projectGraph.Answers.Select();
foreach (CSAnswers att in answers)
{
if (att.AttributeID == "ESTHOURS")
{
att.Value = "20";
}
}
projectGraph.Actions.PressSave();
}
}
baseMethod();
}
But still it is not updating the value.
The thing to realize is that the attribute system is different that the usual DAC->SQL system. CSAnswers is a unnormalized table of values for all the attributes. They are linked to a DAC document by RefNoteID. See select * from CSAnswers where AttributeID = 'ESTHOURS' In the code above you are altering every project's 'esthours'. You're also missing a statement where you tell the graph to update the cache with your altered object. Something like projectGraph.Answers.Update(att);
We have a Sharepoint site which uses search.
We get the following error:
Unable to validate data. at
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData
(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length,
IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
After a bit of testing we have found that the error occurs when we use DateKeyNames on a GridView control.
Not sure why there should be any combination between Search, this error and DataKeyNames.
Any ideas?
Update: Here is some code
[Guid("8891224e-e830-4ffa-afbd-f789583d8d14")]
public class TestErrorGridView : System.Web.UI.WebControls.WebParts.WebPart
{
Control ascxToAdd;
public TestErrorGridView()
{
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
protected override void CreateChildControls()
{
base.CreateChildControls();
Table test = new Table();
TestBindObject t1 = new TestBindObject() { ID = 1, Name = "Test" };
List<TestBindObject> l1 = new List<TestBindObject>();
l1.Add(t1);
SPGridView testGrid = new SPGridView() { AutoGenerateColumns = false};
BoundField header = new BoundField();
header.DataField = "ID";
BoundField name = new BoundField();
name.DataField = "Name";
testGrid.Columns.Add(header);
testGrid.Columns.Add(name);
testGrid.DataSource = l1;
testGrid.DataBind();
// If you comment out this line search works
testGrid.DataKeyNames = new string[] { "ID" };
this.Controls.Add(testGrid);
base.CreateChildControls();
SPGridView testGrid = new SPGridView() { AutoGenerateColumns = false, EnableViewState=false };
testGrid.DataKeyNames = new string[] { "testid" };
this.Controls.Add(testGrid);
}
}
public class TestBindObject
{
public int ID { get; set; }
public string Name { get; set; }
}
UPDATE
This error occurrs on the developer machines, so it is not realated to machine keys being different on different machines in a cluster.
One of the developers has MOSS installed, he does not get the error. The developers who have just WSS installed get the error.
UPDATE 2
Have added datasource to code
I'm going to throw out a guess here since the code where you set the GridView's datasource is missing as well, but here goes...
It probably has something to do with the order in which you are setting the GridView's properties. My guess is that you need to set it in this order:
Create your GridView
Set the GridView's datasource (so that it has data)
Set DataKeyNames
Call GridView.DataBind()
Step 3 and 4 are the steps I am not sure about. You may have to DataBind and then set DataKeyNames.
We eventually solved this by following the example in this link:
http://msdn.microsoft.com/en-us/library/bb466219.aspx
I think that is was binding to a data table rather than a list that made the difference.
The fact that Sharepoint grids do not allow autogenerated columns appears to be one of the factors leading to this problem.
We have a problem with SharePoint's search box. Whenever we try to search for something we get:
Unable to validate data. at
System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean
fEncrypt, Byte[] buf, Byte[] modifier,
Int32 start, Int32 length, IVType
ivType, Boolean useValidationSymAlgo)
at
System.Web.UI.ObjectStateFormatter.Deserialize(String
inputString) exeption.
Does any one know the reason for this exception, or a way to work around it?
New entry:
I'm using a SPGridView where i use the datakeys property in a web part. The webpart works, but we found that using the datakeys property breaks seach in that if you try to use the search textbox and click the seach button it gets this exception:
Unable to validate data. at System.Web.Configuration.MachineKeySection.EncryptOrDecryptData(Boolean fEncrypt, Byte[] buf, Byte[] modifier, Int32 start, Int32 length, IVType ivType, Boolean useValidationSymAlgo)
at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString)
This is what i have tryed to do:
Make the gridview not spgridview and set autogenerate true (works)
Remove the datakeynames (works)
Test with a empty gridvew (failes)
Test with a non-empty gridview (failes)
Change Machine Keys (failes)
Turn of view state on the gridvew (failes)
Move the gridview ti a ascx file (failes)
I can't seem to figure this one out. Have enyone got this error and been able to work around it?
EDit 10.09.2009
This is the last code I tested. I used a MSDN excample as referance. I have also tried without Data table MSDN Example
public class TestErrorGridView : System.Web.UI.WebControls.WebParts.WebPart
{
Control ascxToAdd;
protected DataTable PropertyCollection = new DataTable();
private DataColumn key;
public TestErrorGridView()
{
key = PropertyCollection.Columns.Add("ID", typeof(string));
PropertyCollection.Columns.Add("Name", typeof(string));
}
public void AddProperty(TestBindObject data)
{
DataRow newRow = PropertyCollection.Rows.Add();
newRow["ID "] = data.ID;
newRow["Name"] = data.Name;
}
public void BindGrid(SPGridView grid)
{
SPBoundField fldPropertyName = new SPBoundField();
fldPropertyName.HeaderText = "ID";
fldPropertyName.DataField = "ID";
grid.Columns.Add(fldPropertyName);
SPBoundField fldPropertyValue = new SPBoundField();
fldPropertyValue.HeaderText = "Name";
fldPropertyValue.DataField = "Name";
grid.Columns.Add(fldPropertyValue);
PropertyCollection.PrimaryKey = new DataColumn[] { key };
grid.DataSource = PropertyCollection.DefaultView;
grid.DataKeyNames = new string[] { key.ColumnName };
grid.DataBind();
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
}
protected override void CreateChildControls()
{
base.CreateChildControls();
TestBindObject t1 = new TestBindObject() { ID = 1, Name = "Test3" };
this.AddProperty(t1);
SPGridView testGrid = new SPGridView() { AutoGenerateColumns = false };
this.BindGrid(testGrid);
this.Controls.Add(testGrid);
}
}
[Serializable]
public class TestBindObject
{
public int ID { get; set; }
public string Name { get; set; }
}
From the error message I'd say that you are operating in a web-farm environment. Have you set the same machineKey in each of the SharePoint web.config files? See this link for a little more info.