Issue of creating new item using PXAction in Acumatica - acumatica

I encounter an issue when using PXAction to create new item in Acumatica and appreciate you can give me a help.
I added the custom auto-increment attribute for the "DocumentNbr" field in my "Document" DAC following the Acumatica official document's example "Example 8.2: Creating the Custom AutoNumber Attribute" in the T200 Document as below.
Here is the snippet of code of the attribute setting for the "DocumentNbr" field:
#region DocumentNbr
protected string _DocumentNbr;
[PXDBString(15, IsUnicode = true, IsKey = true, InputMask = ">CCCCCCCC")]
[PXSelector(typeof(Search<MABUIPDocument.documentNbr>),
typeof(MABUIPDocument.documentNbr),
typeof(MABUIPDocument.documentDate),
typeof(MABUIPDocument.status),
typeof(MABUIPDocument.vendorID)
)]
[AutoNumber(typeof(MABUIPSetup.autoDocumentNbr), typeof(MABUIPSetup.lastDocumentNbr))]
[PXDefault()]
[PXUIField(DisplayName = "ID")]
public string DocumentNbr
{
get
{
return this._DocumentNbr;
}
set { this._DocumentNbr = value; }
}
public class documentNbr : IBqlField { }
#endregion
It is working fine that I can add, edit and delete documents normally as below:
I have a requirement that creates a new item when clicking button, so I created the "Test Creating new item" button including creating new item logic as below, in my understanding, it would show the created item after clicked the "Test Creating new item" button.
public PXAction<MABUIPDocument> BtnCreatingNew;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Test Creating new item", Visible = true)]
protected virtual void btnCreatingNew()
{
MABUIPDocument row = Documents.Current;
row.DocumentDesc = "Test" + DateTime.Now.ToString();
row = Documents.Update(row);
Actions.PressSave();
}
The actually circumstance is although the new row has been inserted into the database and will occur if I click the "Next" arrow but the form content of the current view is cleared after clicking the button, I tried many methods like setting "Document.Current = row" and "sender.SetValue(row, fieldName, fieldNewValue)" but the content has been keeping blank after clicking the button whatever I tried. Can you please give me a hint what possible reason caused the issue? Thank you very much!

Because your ID value is only generated while new document is saved in the database, you must accordingly update PXAdapter's Searches collection with the actual ID value saved in the database:
public PXAction<MABUIPDocument> BtnCreatingNew;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Test Creating new item", Visible = true)]
protected virtual IEnumerable btnCreatingNew(PXAdapter adapter)
{
MABUIPDocument row = Documents.Current;
row.DocumentDesc = "Test" + DateTime.Now.ToString();
row = Documents.Update(row);
Actions.PressSave();
adapter.Searches[adapter.Searches.Length - 1] = row.DocumentNbr;
return adapter.Get();
}

Related

Adding Custom Entity Type in CRM Activity for selecting in Relative Entity

I have implemented CRM activity on the Custom page where the Key Field is SOOrder Type, SOOrder Nbr & Job Code which are stored in custom DAC. I have tried to add the Entity Type listed on Related Entity and I am not able to figure out how to do it. Pls let me know where to add or override the method to Implement the functionality
The following cod used to implement the CRM Activity
public sealed class SOOrderJobActivities : CRActivityList<PSSOOrderJob>
{
public SOOrderJobActivities(PXGraph graph)
: base(graph) { }
protected override RecipientList GetRecipientsFromContext(NotificationUtility utility, string type, object row, NotificationSource source)
{
var recipients = new RecipientList();
var order = _Graph.Caches[typeof(PSSOOrderJob)].Current as PSSOOrderJob;
if (order == null || source == null)
return null;
SOOrder ord = SOOrder.PK.Find(_Graph, order.OrderType, order.OrderNbr);
var contact = SOOrder.FK.Contact.FindParent(_Graph, ord);
if (contact == null || contact.EMail == null)
return null;
recipients.Add(new NotificationRecipient()
{
Active = true,
AddTo = RecipientAddToAttribute.To,
Email = contact.EMail
});
source.RecipientsBehavior = RecipientsBehaviorAttribute.Override;
return recipients;
}
}
Update
After going through the Acumatica code, I have done the following changes
#region Noteid
[PXNote(ShowInReferenceSelector =true,Selector =typeof(Search2<PSSOOrderJob.jobCode,
InnerJoin<SOOrder,On<PSSOOrderJob.orderType,Equal<SOOrder.orderType>,And<PSSOOrderJob.orderNbr, Equal<SOOrder.orderNbr>>>>,
Where<SOOrder.orderType,Equal<Current<PSSOOrderJob.orderType>>,And<SOOrder.orderNbr, Equal<Current<PSSOOrderJob.orderNbr>>>>>))]
public virtual Guid? Noteid { get; set; }
public abstract class noteid : PX.Data.BQL.BqlGuid.Field<noteid> { }
#endregion
The entity comes into selection, But I am not able to select the relative entity document and the value is not getting updated in the related entity field.
The above screenshot the select is missing and not able to select the document
The following steps I have done to add relative Entity for any Activity using custom DAC
1. Added ShowInReferenceSelector = true in PXNoteID field.
2. Added Selector in PXNoteID field
3. Decorated [PX.Data.EP.PXFieldDescription] attribute for Key fields
#region NoteID
[PXNote(ShowInReferenceSelector = true, Selector = typeof(Search2<PSSOOrderJob.jobCode,
InnerJoin<SOOrder, On<PSSOOrderJob.orderType, Equal<SOOrder.orderType>, And<PSSOOrderJob.orderNbr, Equal<SOOrder.orderNbr>>>>,
Where<SOOrder.orderType, Equal<Current<PSSOOrderJob.orderType>>, And<SOOrder.orderNbr, Equal<Current<PSSOOrderJob.orderNbr>>,And<PSSOOrderJob.jobType,Equal<Current<PSSOOrderJob.jobType>>>>>>), DescriptionField = typeof(PSSOOrderJob.jobCode))]
//[PXNote(ShowInReferenceSelector = true)]
public virtual Guid? NoteID { get; set; }
public abstract class noteID : PX.Data.BQL.BqlGuid.Field<noteID> { }
#endregion
#region JobCode
[PXDBString(15, IsKey = true, IsUnicode = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXUIField(DisplayName = "Job Code")]
[PXDefault()]
[PXSelector(typeof(Search<PSSOOrderJob.jobCode, Where<PSSOOrderJob.orderType, Equal<Current<PSSOOrderJob.orderType>>, And<PSSOOrderJob.orderNbr, Equal<Current<PSSOOrderJob.orderNbr>>,And<PSSOOrderJob.jobType, Equal<Current<PSSOOrderJob.jobType>>>>>>), typeof(PSSOOrderJob.jobCode), ValidateValue = false)]
[PSSOOrderJobNbr.Numbering()]
[PX.Data.EP.PXFieldDescription]
public virtual string JobCode { get; set; }
public abstract class jobCode : PX.Data.BQL.BqlString.Field<jobCode> { }
#endregion
This automatically fills the related entity field with Jobcode.
There still one issue I am facing is not able to access the selector due to Entity field width is more than the popup window and I do not know how to fix it.
This answer is to address the popup size only.
First, give browser zoom a try 'control' + 'minus' key. It might work as a quick workaround.
Otherwise, use the browser debugger feature. Open it with F12 key. Then use the browser debugger inspect element feature (1). Click on the smart panel (2). Go up a bit in html control hierarchy until you reach and select the smart panel root which is a table element (3). Change the width of the smart panel popup using the debugger CSS properties editor (4).
If selector control size increases automatically with window size; change the selector control width instead of popup width using browser debugger CSS property editor.

Load value from popup to InventoryID field

am generating a pop on one new button click in stock Items screen, inside popup have two buttons, user select some data from fields in the popup and then click on ok, then inventoryId should be formed with some special characters and then it should display in InventoryID field. I can form the InventoryID but unable to display it in InventoryID field.
[PXButton]
[PXUIField(DisplayName = "Generate")]
public virtual void GenerateInv()
{
InventoryItemExt ext = Base.Item.Cache.GetExtension<InventoryItemExt>(Base.Item.Current);
Base.Item.Current.InventoryCD = ext.UsrInvId;
Base.Item.Cache.Insert(Base.Item.Current);
}
I had this issue before,
and the following code was provided by acumatica. you may try the same.
here in the below code, inventoryCD contains the value, i wanted to set.
InventoryItem item = PXCache<InventoryItem>.CreateCopy(Base.Item.Current);
OrderedDictionary keys = new OrderedDictionary(StringComparer.OrdinalIgnoreCase)
{
{
typeof(InventoryItem.inventoryCD).Name,
adapter.View.Cache.GetValue(adapter.View.Cache.Current,
typeof(InventoryItem.inventoryCD).Name)
}
};
OrderedDictionary vals = new OrderedDictionary(StringComparer.OrdinalIgnoreCase)
{
{
typeof(InventoryItem.inventoryCD).Name, inventoryCD
}
};
adapter.View.Cache.Update(keys, vals);
if (adapter.Searches != null && adapter.Searches.Length > 0)
{
adapter.Searches[0] = inventoryCD;
}
return adapter.Get();
Also make sure your function have the correct input and the return type
IEnumerable GenerateInv(PXAdapter adapter)

How to implement auto generating document number on custom screen

I have a requirement to create a opportunity like screen and I do not know how to implement the auto generating the document number for newly created document
I am looking forward someone to help me on this issue.
The following steps I have used and I have attached the code for review. I am getting error while saving and not generating the number
I have create a numbering sequence for Memo In document
I have created a DAC for Sequence number setup
region MemoInOrderId
public abstract class memoInOrderId : PX.Data.IBqlField
{
}
protected string _MemoInOrderId;
[PXDBString(10, IsUnicode = true)]
[PXDefault("MEMOIN")]
[PXSelector(typeof(Numbering.numberingID),
DescriptionField = typeof(Numbering.descr))]
[PXUIField(DisplayName = "Memo In Order Nbr")]
public virtual string MemoInOrderId
{
get
{
return this._MemoInOrderId;
}
set
{
this._MemoInOrderId = value;
}
}
#endregion
I have added Auto Generation Sequence number to MemoIn DAC
`
#region OrderNbr
public abstract class orderNbr : PX.Data.IBqlField
{
}
[PXDBString(10, IsUnicode = true, IsKey = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXUIField(DisplayName = "Order Nbr", Visibility = PXUIVisibility.SelectorVisible)]
[AutoNumber(typeof(MemoSetUp.memoInOrderId), typeof(AccessInfo.businessDate))]
[PXSelector(typeof(MemoIN.orderNbr),
new Type[]
{
typeof(MemoIN.orderNbr),
typeof(MemoIN.orderDate),
typeof(MemoIN.vendorId)
})]
public virtual string OrderNbr { get; set; }
#endregion
In the configuration Screen I have selected numbering sequence used for memo in document
While saving the Memo In document I am getting the following error
I have noticed the Order number is not initialized to "NEW" and it is showing "SELECT"
I have gone through CASetup , CMSetup , ARSetup DAC code and not able to figure out the difference.
If we want to use a numbering sequence it is very straight forward in Acumatica. You should have a setup/preferences field somewhere that defines which numbering sequence you will use for your document number field.
Here is an example of a setup field using a selector to pick a numbering sequence:
// Setup field indicating which numbering sequence to use.
public abstract class myNumberingID : PX.Data.IBqlField
{
}
protected String _MyNumberingID;
[PXDBString(10, IsUnicode = true)]
[PXSelector(typeof(Numbering.numberingID), DescriptionField = typeof(Numbering.descr))]
[PXUIField(DisplayName = "My Numbering Sequence")]
public virtual String MyNumberingID
{
get
{
return this._MyNumberingID;
}
set
{
this._MyNumberingID = value;
}
}
Next, in your document number field you will use the AutoNumberAttribute to define the field as a consumer of a numbering sequence. Below is an example of a number field using the defined number sequence configured in the setup table above (Assumes "MyNumberingID" exists in DAC/Table "MySetup").
// Field using the numbering sequence...
public abstract class myNumberField : PX.Data.IBqlField
{
}
protected String _MyNumberField;
[PXDBString(15, IsUnicode = true, IsKey = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXUIField(DisplayName = "My Number", Visibility = PXUIVisibility.SelectorVisible)]
[AutoNumber(typeof (MySetup.myNumberingID), typeof (AccessInfo.businessDate))]
[PXDefault]
public virtual String MyNumberField
{
get
{
return this._MyNumberField;
}
set
{
this._MyNumberField = value;
}
}
Edit: Make sure in the graph building the documents to include a PXSetup view to the setup table.
Now when you insert and persist a new record on the DAC that contains your number field, the next numbering sequence value will be used (unless the numbering sequence is configured for manual numbering then the user must provide a value).
For a more complex configuration when there are multiple numbering sequences used based on specific conditions/field values, you can look at PX.Objects.IN.INRegister.RefNbr for an example. Look at INDocType.Numbering and how it changes the numbering sequence based on INRegister.docType (shown below). Another example would be sales order order types related to the sales order document.
public class NumberingAttribute : AutoNumberAttribute
{
public NumberingAttribute()
: base(typeof(INRegister.docType), typeof(INRegister.tranDate),
new string[] { Issue, Receipt, Transfer, Adjustment, Production, Change, Disassembly },
new Type[] { typeof(INSetup.issueNumberingID), typeof(INSetup.receiptNumberingID), typeof(INSetup.receiptNumberingID), typeof(INSetup.adjustmentNumberingID), typeof(INSetup.kitAssemblyNumberingID), typeof(INSetup.kitAssemblyNumberingID), typeof(INSetup.kitAssemblyNumberingID) }) { ; }
}

Acumatica Extension on SOSitesStatusSelected

I've been having this problem on Acumatica extension for days now and can't seem to figure out the resolution. I've added an action on the Inventory Lookup Dialog of Sales Order screen (see screenshot below), the action is task to update the QtySelected to 1 and also to update my added Field which is the Brand to "testBrand". It is an extension of the SOSitesStatusSelected table, but whenever i clicked on the action, it only updates QtySelected and not my added Field Brand.
You may refer to my code below, thank you and I appreciate all the help.
//DAC
#region UsrBrand
[PXUIField(DisplayName = "Brand", Visible = true, Enabled = true)]
public virtual string UsrBrand{get;set;}
public abstract class usrBrand : IBqlField{}
#endregion
//BLC
public PXAction<PX.Objects.SO.SOOrder> updateAttributes;
[PXButton(CommitChanges = true)]
[PXUIField(DisplayName = "Update Attributes")]
protected void UpdateAttributes()
{
this.Base.sitestatus.AllowInsert= true;
this.Base.sitestatus.AllowUpdate= true;
foreach (SOSiteStatusSelected line in this.Base.sitestatus.Select())
{
line.QtySelected = 1;
this.Base.sitestatus.Update(line);
SOSiteStatusSelectedExt rowExt = this.Base.sitestatus.Cache.GetExtension<SOSiteStatusSelectedExt>(line);
rowExt.UsrBrand = "testBrand";
this.Base.sitestatus.Cache.Update(rowExt);
}
}
In this case your extension SOSiteStatusSelectedExt is not a separate item. It's a part of the base record actually. So you don't need to update it separately.
line.QtySelected = 1;
SOSiteStatusSelectedExt rowExt = this.Base.sitestatus.Cache.GetExtension<SOSiteStatusSelectedExt>(line);
rowExt.UsrBrand = "testBrand";
this.Base.sitestatus.Update(line);

Print button on CR306000 to print case data

I have a custom button on CR306000 to try to print current loaded case information by calling one customized report. Navigation URL current set to:
~/Frames/ReportLauncher.aspx?ID=Inquirycase.rpx&CASEID=####
I will need to have custom programming to assign current case ID to replace "####", but don't know where and how to reference that custom button and modify its property. Please help. Thanks.
You could add a report parameter called 'CaseID' to your report and call it using the following code using an AEF extension like this:
public class CRCaseMaintExtension : PXGraphExtension<CRCaseMaint>
{
public override void Initialize()
{
base.Initialize();
//if adding to an existing menu button do that here...
// Example:
//Base.Inquiry.AddMenuAction(this.CustomReportButton);
}
public PXAction<CRCase> CustomReportButton;
[PXButton]
[PXUIField(DisplayName = "Custom Report", MapEnableRights = PXCacheRights.Select, MapViewRights = PXCacheRights.Select)]
public virtual IEnumerable customReportButton(PXAdapter adapter)
{
if (Base.Case.Current != null)
{
Dictionary<string, string> parameters = new Dictionary<string, string>();
parameters["CaseID"] = Base.Case.Current.CaseID.ToString();
//enter in your report id/number here
string reportNumber = "Inquirycase";
//opens the report using the defined parameters
throw new PXReportRequiredException(parameters, reportNumber, "Custom Report");
}
return adapter.Get();
}
}
I have not tested the above but this should get you most of the way there.

Resources