I have a view delegate to sort items. Which is working fine. But the issue is, hyperlink is not picking up current record, it is picking up the first record. Here is my sample code:
protected virtual void viewname()
{
PXView query = new PXView(this, true, this.viewname.View.BqlSelect);
query.OrderByNew<OrderBy<Asc<DACname.field1, Desc<DACname.field2,
Desc<DACname.field3>>>>>();
}
Remove the view delegate and try to add the order by directly into the data view like Evgeny Kralko example [2.Don't try to sort items via delegate, you should do it via BQL view declaration]
Remove the view delegate and move the query.OrderByNew<OrderBy<Asc<DACname.field1, Desc<DACname.field2, Desc<DACname.field3>>>>>(); into graph ctor or Initialize() if graph extension.
Example:
public GraphName()
{
this.ViewName.OrderByNew<OrderBy<Asc<DACName.field>>>();
}
1.First of all, please try to add SyncPosition="True" expression to your ASPX file:
<px:PXGrid runat="server" SyncPosition="True" ...
2.Don't try to sort items via delegate, you should do it via BQL view declaration
PXSelect<ARTax, ...,
OrderBy<Asc<ARTax.tranType, Asc<ARTax.refNbr, Asc<ARTax.taxID>>>>> Tax_Rows;
3.Looks like something wrong with your delegate declaration, try to return items from there, something like this:
public virtual IEnumerable taxes()
{
foreach (PXResult<ARTaxTran, Tax> res in PXSelectJoin<ARTaxTran,
LeftJoin<Tax, On<Tax.taxID, Equal<ARTaxTran.taxID>>>,
Where<ARTaxTran.module, Equal<BatchModule.moduleAR>,
And<ARTaxTran.tranType, Equal<Current<ARInvoice.docType>>,
And<ARTaxTran.refNbr, Equal<Current<ARInvoice.refNbr>>>>>>.Select(this))
{
...
yield return res;
}
}
Related
I need to add a filter to the Process Orders screen grid, so that only orders that have an unpaid balance = 0 will show, based on an additional checkbox to the filter area called 'Must Have Payment' being checked. I thought I had it by adding a where clause to the Orders view, but that didn't work.
[PXFilterable]
public PXFilteredProcessing<SOOrder, SOOrderFilter,
Where<SOOrder.unpaidBalance, NotEqual<Zero>,
Or<Current<SOOrderFilterExt.mustHavePayment>, Equal<False>>>> Orders;
I'm sure I'm doing this incorrectly, as all orders are showing and not just the 'Open' orders as it was before I added this change. I'd like to override the view delegate and modify that to add my filter / condition to the returned rows, but I can't override this method - at least that I can tell.
What's the best way to get this custom filter restriction into the select for that grid?
Thanks much...
Overriding the dataview delegate may not be the best idea on this specific case.
I noticed that AddCommonFilters() method is not private (used in the dataview delegate), so I think you could try to override this method instead, call Base method and then inject your custom code to include your query filter into the main query used on the for each.
Maybe this is something you can use to implement your filtering, see snippet below:
public class SOCreateShipment_Extension : PXGraphExtension<SOCreateShipment>
{
#region Event Handlers
public delegate void AddCommonFiltersDelegate(SOOrderFilter filter,
PXSelectBase<SOOrder> cmd);
[PXOverride]
public void AddCommonFilters(SOOrderFilter filter, PXSelectBase<SOOrder> cmd, AddCommonFiltersDelegate baseMethod)
{
baseMethod(filter,cmd);
//Add your custom code here
if (Yourcondition)
{
cmd.WhereAnd<Where<YOURFILTERINGCondition>>>>();
}
}
........................
Please also review the AlterFilters() method if needed.
I'm trying to modify the Generate Recurring Transactions (GL504000) screen, and I want to add a user field to filter the grid. I've added a UsrRecurringClass user field to DAC extensions of both the 'Parameters' DAC for the header, and the 'Schedule' DAC for the grid. Now I want to filter that grid by the selection I've added to the header (The UsrRecurringClass field I've added to both)
The problem is, I can't add that field to the View select (Schedule_List) and have it make any difference (I did set the CommitChanges to true on the header filter field).
I've added this to graph extension of the 'ScheduleRun' BLC, as follows, but it doesn't seem to make any difference...
[PXFilterable]
public PXFilteredProcessing<Schedule, ScheduleRun.Parameters,
Where2<Where<ParametersExt.usrRecurringClass, IsNull, Or<ScheduleExt.usrRecurringClass, Equal<Current<ParametersExt.usrRecurringClass>>>>,
And2<Where<Schedule.active, Equal<True>>,
And<Schedule.nextRunDate, LessEqual<Current<ScheduleRun.Parameters.executionDate>>>>>> Schedule_List;
Maybe I'm not doing the BQL correctly, or there's a better way, using the View delegate - I'm not sure.
Any ideas?
I have done a similar customization, maybe the pattern will help you.
public class ARCreateWriteOff_Extension : PXGraphExtension<ARCreateWriteOff>
{
#region Event Handlers
// First expose the PXFilterable view in the extension
[PXFilterable]
[PX.SM.PXViewDetailsButton(typeof(ARRegisterEx.refNbr), WindowMode = PXRedirectHelper.WindowMode.NewWindow)]
public PXFilteredProcessingJoin<ARRegisterEx> ARDocumentList;
// the ARDocumentList view is a long BQL statement I just removed most of it for the example
// Over write the IEnumerabel
protected virtual IEnumerable aRDocumentList()
{
// Get the current row and its extention
ARWriteOffFilter aRWriteOffFilter = Base.Filter.Current;
ARWriteOffFilterExt aRWriteOffFilterExt = aRWriteOffFilter.GetExtension<ARWriteOffFilterExt>();
// loop the values
foreach (ARRegisterEx item in Base.ARDocumentList.Select())
{
//check if the field is Null to return all data
if (string.IsNullOrWhiteSpace(aRWriteOffFilterExt.UsrEmployeeID))
{
yield return item;
}
else
{
// Here you will check if your filter matches the row level
if (aRWriteOffFilterExt.UsrEmployeeID == bAccountExt.UsrEmployeeID)
{
yield return item;
}
}
}
}
I was searching for a solution to add a note to a database row I am creating in a custom table. I found the solution below from Ruslan for accessing the noteid, but I don't understand how this would be used to add a note to the row. I have all the code to create the row, I just need the attributes or function call to actually attach the text of the note to the row.
==================================================================
To have Note record automatically created when a new parent record gets saved, one should invoke the static PXNoteAttribute.GetNoteID(PXCache cache, object data) method when the parent record is inserted in the cache.
For example, to have Note record automatically created when a new Stock Item gets saved, you should subscribe to RowInserted handler for the InventoryItem DAC and call PXNoteAttribute.GetNoteID(...):
public class InventoryItemMaintExt : PXGraphExtension<InventoryItemMaint>
{
public void InventoryItem_RowInserted(PXCache sender, PXRowInsertedEventArgs e)
{
var noteCache = Base.Caches[typeof(Note)];
var oldDirty = noteCache.IsDirty;
PXNoteAttribute.GetNoteID<InventoryItem.noteID>(sender, e.Row);
noteCache.IsDirty = oldDirty;
}
}
The code snippet above can be incorporated into almost any custom BLC with a couple simple changes to replace InventoryItem with a custom DAC.
After implementing Gabriel's suggestions:
I do not seem to get any note in the database. The code compiles and runs fine, but the notes are not generated as far as I can tell. The note id is set in my table, but no data appears in the note table. Please take a look at my code and let me know what needs to change. Also, how do I get the note column into a grid, or does it automatically become available when it is done correctly?
Database field definition:
[NoteID] [uniqueidentifier] NULL
DAC field:
#region NoteID
public abstract class noteID : PX.Data.IBqlField
{
}
protected Guid? _NoteID;
[PXNote()]
public virtual Guid? NoteID
{
get
{
return this._NoteID;
}
set
{
this._NoteID = value;
}
}
#endregion
Code to create record:
private static bool acumaticaException(Exception e, EDImportExceptionMaint excpMaint, LingoRet850 res850)
{
excpMaint.Clear();
var except = new EDImportExcept();
except.ExceptReason = "U";
except.Active = true;
<...field assignments...>
except.OrderNbr = "";
PXNoteAttribute.SetNote(excpMaint.Exception.Cache, excpMaint.Exception.Current,
((PX.Data.PXOuterException)e).InnerMessages[0] + "-" + e.Message);
excpMaint.Exception.Insert(except);
excpMaint.Actions.PressSave();
return true;
}
To set the note of a record, use the SetNote()static function of PXNoteAttribute
PXNoteAttribute.SetNote(Base.Item.Cache, Base.Item.Current, "Hello, World!");
Calling SetNote will also take care of adding the Note record if it doesn't exist, so you don't have to call GetNoteID before setting the note value as in your question.
P.S. There is also a GetNote function which allows you to retrieve the current value of the note:
string note = PXNoteAttribute.GetNote(Base.Item.Cache, Base.Item.Current);
I want to disable Orchard Content Part buttons (Save and Publish Now) in the EDITOR template (when Content Item is created) based on some conditions. Can I do that ? How do I access the buttons in the EDITOR view.
Here are come examples,
To build a content fully from a Controller example, taken from the Blog Module
public ActionResult Create() {
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to create blogs")))
return new HttpUnauthorizedResult();
BlogPart blog = Services.ContentManager.New<BlogPart>("Blog");
if (blog == null)
return HttpNotFound();
dynamic model = Services.ContentManager.BuildEditor(blog);
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
return View((object)model);
}
[HttpPost, ActionName("Create")]
public ActionResult CreatePOST() {
if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't create blog")))
return new HttpUnauthorizedResult();
var blog = Services.ContentManager.New<BlogPart>("Blog");
_contentManager.Create(blog, VersionOptions.Draft);
dynamic model = _contentManager.UpdateEditor(blog, this);
if (!ModelState.IsValid) {
_transactionManager.Cancel();
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
return View((object)model);
}
_contentManager.Publish(blog.ContentItem);
return Redirect(Url.BlogForAdmin(blog));
}
BuidEditor does the work for you.
And you should use a alternative version of this template, but remove the edit link and publish link.
Note, you need a route for you custom create action, and a menu link on the dashboard may come in handy.
I've got the following problem:
I created a WebPart with a ToolPart,
this toolpart has multiple controls (textbox, dropdownlist, ...)
when I fill in everything and apply, it all goes ok,
even when i press ok. But when i go back to
edit -> modify webpart, all my data i've entered is gone.
How can i solve this?
Thanks
You'll need to save the values from the Toolpart in the webpart's properties. For example, lets say I want to save a string for "Title"... in the webpart define a property:
private const string DEFAULT_WPPColumnTitle = "Title";
private string _WPPColumnTitle = DEFAULT_WPPColumnTitle;
[Browsable(false)]
[WebPartStorage(Storage.Shared)]
public string WPPColumnTitle
{
get { return this._WPPColumnTitle; }
set { this._WPPColumnTitle = value; }
}
I always use the prefix "WPP" to keep all the web part properties together.
Then, in the Toolpart's ApplyChanges override, save the control's value (_ddlColumnsTitle) to the webpart (WPPColumnTitle):
/// <summary>
/// Called by the tool pane to apply property changes to
/// the selected Web Part.
/// </summary>
public override void ApplyChanges()
{
// get our webpart and set it's properties
MyCustomWebPart et = (MyCustomWebPart)ParentToolPane.SelectedWebPart;
et.WPPColumnTitle = _ddlColumnsTitle.SelectedValue;
}
Lastly, if the user edited the properties already, we want the Toolpart to be pre-populated with the user's configuration. In the CreateChildControls() method of your Toolpart, initialize the controls:
protected override void CreateChildControls()
{
try
{
MyCustomWebPart et = (MyCustomWebPart)ParentToolPane.SelectedWebPart;
// ... code to create _ddlColumnsTitle and add it to the Controls
// default our dropdown to the user's selection
ListItem currentItem = _ddlColumnsTitle.Items.FindByValue(et.WPPColumnTitle);
if (null != currentItem)
{
_ddlColumnsTitle.SelectedValue = currentItem.Value;
}
}
catch (Exception ex)
{
_errorMessage = "Error adding edit controls. " + ex.ToString();
}
}
Open up the debugger and double check that the values are getting applied to your propertries on Apply (i.e. WPPColumnTitle is set).
If so then problem is that SharePoint is not serializing/deserializing the value from the property (WPPColumnTitle) to the database and back - verify by writing out this property on the web part - as soon as you leave the page and come back it will be empty.
If so then check things like this on class
[XmlRoot(Namespace = "YourNamespace")]
and this (not strictly necessary) on properties
[XmlElement(ElementName = "ColumnTitle")]
I've also seen problems if you name your web part class "WebPart" so call it MyWebPart
I've solved it with adding a property in my webpart "IsNeverSet" (bool)
and when i go to the "CreateControls()" of my toolpart, I get this property
and if it's false, I load all the properties from my webpart and fill them in the toolpart.
So I found it with the help of Kit Menke