@rosenjon @Dioris Aguilar
Try to change
update container "HeaderView" {
with
update container "StockItemSummary" {
Also confirm that you see the exact action name “PrintItemLabel” under Tools > Web Service > Service Description
@Fernando Amadoz Thanks for your reminder about checking the Web Service section.@rosenjon This ItemLookup screen actually has a dynamic data source:
Hence, the action should be defined as a graph extension of at least one of those graphs:
public class InventoryItemLookup_Extension : PXGraphExtension<PX.Objects.IN.WMS.InventoryItemLookup.Host> { public PXAction<PX.BarcodeProcessing.ScanHeader> PrintItemLabel; PXButton(CommitChanges = true), PXUIField(DisplayName = "Print Item Label")] public virtual IEnumerable printItemLabel(PXAdapter adapter) { return adapter.Get(); } //optional //protected void _(Events.RowSelected<PX.BarcodeProcessing.ScanHeader> e) //{ // PrintItemLabel.SetVisible(Base.IsMobile); //} }
In this case, it seems enough to define it as a graph extension of PX.Objects.IN.WMS.InventoryItemLookup.Host.
And the mobile customization will be as follows:
update screen IN202520 { update container "HeaderView" { update layout "FooterLayout" { update layout "Line1" { remove recordActionLink "ScanBarcode" add recordActionLink "PrintItemLabel" } } add recordAction "PrintItemLabel" { displayName = "Print Label" behavior = Void } } }
In order to make the custom action available in the mobile app:
@Dioris Aguilar I finally was able to make my way through your example. I got hung up on referencing an assembly for PX.BarcodeProcessing.dll. I am including a screenshot of how to do that below. I am still confused why that assembly cannot be refefereced with a simple “using” directive in Visual Studio. I think maybe what’s happening in this mobile screen is that it’s referencing both the old and new WMS versions in Acumatica in a single screen. In most cases, the user has either activated the old or the new WMS, but for this mobile screen it is addressing both assemblies at once. Therefore, you end up having to deal with code paths for both new and old WMS systems together, even if you are using only one. Do you think that makes sense for why this works the way it does and requires the same method using two different dlls?
I can honestly say that in 1,000 years, I probably would never have figured this out without your help, so I am extremely grateful for your patience walking me through this. At the same time, it’s kind of a “shame on Acumatica” thing for this being so obscure and non-obvious and at the same time totally undocumented.
Anyway, the result seems to work pretty well, even if the process to get there was somewhat obscure.
@rosenjon behavior = PrintItemLabel does not seem to be a right selection for recordAction. According to documentation valid values of behavior are: Cancel, Create, Delete, Open, Record, Save, SignReport and Void. Try assigning a valid value, this value will depend on the purpose of the the action itself.
@rosenjon For sure you can do that, probably you are not able to do it because you are assigning a wrong value to Behavior. Here you have a list and explanation for every valid value for this property: https://help-2022r1.acumatica.com/Help?ScreenId=ShowWiki&pageid=6d93c127-423c-4597-82c3-6f3fff4bf5ab
Hi @Dioris Aguilar -
I am trying to connect a button in the mobile app to a custom PXAction that I wrote in an extension library. There must be a way to trigger a PXAction from the mobile app that isn’t one of the stock actions, right?
Thanks,
Jonathan
I’ve tried Void also. Didn’t change anything….
Hi @Dioris Aguilar -
Thank you so much for this very specific example. I am not yet able to replicate what you have shown here, but this has gotten me a lot closer. Thank you for describing the specific graph extension that I need to reference in order to add my new method and have it be available to the mobile app code.
What both you and @Fernando Amadoz are pointing out, and was reinforced with the recent Coffee + Code on mobile app development, is that the mobile app appears to have a tight connection to the screen based SOAP API in Acumatica. So the methods available to the mobile app are those available to the screen based SOAP API.
The piece I’m still missing is when I create my graph extension as you have shown above (i.e. PXGraphExtension<PX.Objects.IN.WMS.InventoryItemLookup.Host>), how do I then make my printItemLabel method available to the SOAP API for that screen, in order for the MSDL for the mobile site to be able to reference it? The PrintItemLabel action is not available in the “Actions” section of my xml file location at: http://xmysitex.com/(W(1))/SOAP/IN202520.asmx?WSDL , so I assume that is the reason my recordAction code in my msdl is still not working….
Thanks,
Jonathan
This XML file does not appear to have any style information associated with it. The document tree is shown below. <wsdl:definitions xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://www.acumatica.com/typed/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" targetNamespace="http://www.acumatica.com/typed/"> <wsdl:types> <s:schema elementFormDefault="qualified" targetNamespace="http://www.acumatica.com/typed/"> <s:element name="Clear"> <s:complexType/> </s:element> <s:element name="ClearResponse"> <s:complexType/> </s:element> <s:element name="GetProcessStatus"> <s:complexType/> </s:element> <s:element name="GetProcessStatusResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="GetProcessStatusResult" type="tns:ProcessResult"/> </s:sequence> </s:complexType> </s:element> <s:complexType name="ProcessResult"> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="Status" type="tns:ProcessStatus"/> <s:element minOccurs="1" maxOccurs="1" name="Seconds" type="s:int"/> <s:element minOccurs="0" maxOccurs="1" name="Message" type="s:string"/> </s:sequence> </s:complexType> <s:simpleType name="ProcessStatus"> <s:restriction base="s:string"> <s:enumeration value="NotExists"/> <s:enumeration value="InProcess"/> <s:enumeration value="Completed"/> <s:enumeration value="Aborted"/> </s:restriction> </s:simpleType> <s:element name="GetScenario"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="scenario" type="s:string"/> </s:sequence> </s:complexType> </s:element> <s:element name="GetScenarioResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="GetScenarioResult" type="tns:ArrayOfCommand"/> </s:sequence> </s:complexType> </s:element> <s:complexType name="ArrayOfCommand"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Command" nillable="true" type="tns:Command"/> </s:sequence> </s:complexType> <s:complexType name="Command"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="FieldName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="ObjectName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="Value" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" default="false" name="Commit" type="s:boolean"/> <s:element minOccurs="0" maxOccurs="1" default="false" name="IgnoreError" type="s:boolean"/> <s:element minOccurs="0" maxOccurs="1" name="LinkedCommand" type="tns:Command"/> <s:element minOccurs="0" maxOccurs="1" name="Descriptor" type="tns:ElementDescriptor"/> </s:sequence> </s:complexType> <s:complexType name="ElementDescriptor"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" default="false" name="IsDisabled" type="s:boolean"/> <s:element minOccurs="0" maxOccurs="1" default="false" name="IsRequired" type="s:boolean"/> <s:element minOccurs="0" maxOccurs="1" default="String" name="ElementType" type="tns:ElementTypes"/> <s:element minOccurs="0" maxOccurs="1" default="0" name="LengthLimit" type="s:int"/> <s:element minOccurs="0" maxOccurs="1" name="InputMask" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="DisplayRules" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="AllowedValues" type="tns:ArrayOfString"/> <s:element minOccurs="0" maxOccurs="1" name="Container" type="tns:Container"/> <s:element minOccurs="0" maxOccurs="1" name="ActionIcon" type="s:string"/> <s:element minOccurs="1" maxOccurs="1" name="FieldPriority" type="s:int"/> <s:element minOccurs="1" maxOccurs="1" name="ButtonType" type="tns:PXSpecialButtonType"/> <s:element minOccurs="0" maxOccurs="1" name="LinkCommand" type="s:string"/> <s:element minOccurs="1" maxOccurs="1" name="Visible" type="s:boolean"/> <s:element minOccurs="1" maxOccurs="1" name="IsTimeList" type="s:boolean"/> <s:element minOccurs="1" maxOccurs="1" name="PreserveTime" nillable="true" type="s:boolean"/> <s:element minOccurs="0" maxOccurs="1" name="DependsOn" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="StateColumn" type="s:string"/> </s:sequence> </s:complexType> <s:simpleType name="ElementTypes"> <s:restriction base="s:string"> <s:enumeration value="String"/> <s:enumeration value="AsciiString"/> <s:enumeration value="StringSelector"/> <s:enumeration value="ExplicitSelector"/> <s:enumeration value="Number"/> <s:enumeration value="Option"/> <s:enumeration value="WideOption"/> <s:enumeration value="Calendar"/> <s:enumeration value="Action"/> </s:restriction> </s:simpleType> <s:complexType name="ArrayOfString"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="string" nillable="true" type="s:string"/> </s:sequence> </s:complexType> <s:complexType name="Container"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="Fields" type="tns:ArrayOfField"/> <s:element minOccurs="0" maxOccurs="1" name="Name" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="ServiceCommands" type="tns:ArrayOfCommand"/> <s:element minOccurs="0" maxOccurs="1" name="Children" type="tns:ArrayOfContainer"/> <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string"/> </s:sequence> </s:complexType> <s:complexType name="ArrayOfField"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Field" nillable="true" type="tns:Field"/> </s:sequence> </s:complexType> <s:complexType name="Field"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="Attachment"> <s:complexContent mixed="false"> <s:extension base="tns:Field"/> </s:complexContent> </s:complexType> <s:complexType name="Value"> <s:complexContent mixed="false"> <s:extension base="tns:Field"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="Message" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" default="false" name="IsError" type="s:boolean"/> <s:element minOccurs="0" maxOccurs="1" name="ErrorLevel" type="s:string"/> </s:sequence> </s:extension> </s:complexContent> </s:complexType> <s:complexType name="ArrayOfContainer"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Container" nillable="true" type="tns:Container"/> </s:sequence> </s:complexType> <s:simpleType name="PXSpecialButtonType"> <s:restriction base="s:string"> <s:enumeration value="Default"/> <s:enumeration value="Save"/> <s:enumeration value="SaveNotClose"/> <s:enumeration value="Cancel"/> <s:enumeration value="Refresh"/> <s:enumeration value="CopyPaste"/> <s:enumeration value="Report"/> <s:enumeration value="First"/> <s:enumeration value="Next"/> <s:enumeration value="Prev"/> <s:enumeration value="Last"/> <s:enumeration value="Insert"/> <s:enumeration value="Delete"/> <s:enumeration value="Approve"/> <s:enumeration value="ApproveAll"/> <s:enumeration value="Process"/> <s:enumeration value="ProcessAll"/> <s:enumeration value="Schedule"/> <s:enumeration value="EditDetail"/> <s:enumeration value="ActionsFolder"/> <s:enumeration value="InquiriesFolder"/> <s:enumeration value="ReportsFolder"/> <s:enumeration value="ToolbarFolder"/> <s:enumeration value="SidePanelFolder"/> </s:restriction> </s:simpleType> <s:complexType name="EveryValue"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="Answer"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="RowNumber"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="DeleteRow"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="NewRow"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="Parameter"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="Key"> <s:complexContent mixed="false"> <s:extension base="tns:Command"/> </s:complexContent> </s:complexType> <s:complexType name="Action"> <s:complexContent mixed="false"> <s:extension base="tns:Command"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="ViewTypeName" type="s:string"/> </s:sequence> </s:extension> </s:complexContent> </s:complexType> <s:element name="GetSchema"> <s:complexType/> </s:element> <s:element name="GetSchemaResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="GetSchemaResult" type="tns:Content"/> </s:sequence> </s:complexType> </s:element> <s:complexType name="Content"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="Actions" type="tns:Actions"/> <s:element minOccurs="0" maxOccurs="1" name="HeaderView" type="tns:HeaderView"/> <s:element minOccurs="0" maxOccurs="1" name="ItemInventorySummary" type="tns:ItemInventorySummary"/> <s:element minOccurs="0" maxOccurs="1" name="Mode" type="tns:Mode"/> <s:element minOccurs="0" maxOccurs="1" name="ScanLog" type="tns:ScanLog"/> <s:element minOccurs="0" maxOccurs="1" name="Item" type="tns:Item"/> </s:sequence> </s:complexType> <s:element name="SetSchema"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="schema" type="tns:Content"/> </s:sequence> </s:complexType> </s:element> <s:element name="SetSchemaResponse"> <s:complexType/> </s:element> <s:element name="Export"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="commands" type="tns:ArrayOfCommand"/> <s:element minOccurs="0" maxOccurs="1" name="filters" type="tns:ArrayOfFilter"/> <s:element minOccurs="1" maxOccurs="1" name="topCount" type="s:int"/> <s:element minOccurs="1" maxOccurs="1" name="includeHeaders" type="s:boolean"/> <s:element minOccurs="1" maxOccurs="1" name="breakOnError" type="s:boolean"/> </s:sequence> </s:complexType> </s:element> <s:complexType name="ArrayOfFilter"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Filter" nillable="true" type="tns:Filter"/> </s:sequence> </s:complexType> <s:complexType name="Filter"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="Field" type="tns:Field"/> <s:element minOccurs="1" maxOccurs="1" name="Condition" type="tns:FilterCondition"/> <s:element minOccurs="0" maxOccurs="1" name="Value"/> <s:element minOccurs="0" maxOccurs="1" name="Value2"/> <s:element minOccurs="1" maxOccurs="1" name="OpenBrackets" type="s:int"/> <s:element minOccurs="1" maxOccurs="1" name="CloseBrackets" type="s:int"/> <s:element minOccurs="1" maxOccurs="1" name="Operator" type="tns:FilterOperator"/> </s:sequence> </s:complexType> <s:simpleType name="FilterCondition"> <s:restriction base="s:string"> <s:enumeration value="Equals"/> <s:enumeration value="NotEqual"/> <s:enumeration value="Greater"/> <s:enumeration value="GreaterOrEqual"/> <s:enumeration value="Less"/> <s:enumeration value="LessOrEqual"/> <s:enumeration value="Contain"/> <s:enumeration value="StartsWith"/> <s:enumeration value="EndsWith"/> <s:enumeration value="NotContain"/> <s:enumeration value="Between"/> <s:enumeration value="IsNull"/> <s:enumeration value="IsNotNull"/> <s:enumeration value="Overdue"/> </s:restriction> </s:simpleType> <s:simpleType name="FilterOperator"> <s:restriction base="s:string"> <s:enumeration value="And"/> <s:enumeration value="Or"/> </s:restriction> </s:simpleType> <s:complexType name="ArrayOfArrayOfString"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="ArrayOfString" nillable="true" type="tns:ArrayOfString"/> </s:sequence> </s:complexType> <s:element name="ExportResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="ExportResult" type="tns:ArrayOfArrayOfString"/> </s:sequence> </s:complexType> </s:element> <s:element name="Import"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="commands" type="tns:ArrayOfCommand"/> <s:element minOccurs="0" maxOccurs="1" name="filters" type="tns:ArrayOfFilter"/> <s:element minOccurs="0" maxOccurs="1" name="data" type="tns:ArrayOfArrayOfString"/> <s:element minOccurs="1" maxOccurs="1" name="includedHeaders" type="s:boolean"/> <s:element minOccurs="1" maxOccurs="1" name="breakOnError" type="s:boolean"/> <s:element minOccurs="1" maxOccurs="1" name="breakOnIncorrectTarget" type="s:boolean"/> </s:sequence> </s:complexType> </s:element> <s:complexType name="ImportResult"> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="Processed" type="s:boolean"/> <s:element minOccurs="0" maxOccurs="1" name="Error" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="Keys" type="tns:ArrayOfValue"/> </s:sequence> </s:complexType> <s:complexType name="ArrayOfValue"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Value" nillable="true" type="tns:Value"/> </s:sequence> </s:complexType> <s:complexType name="ArrayOfImportResult"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="ImportResult" nillable="true" type="tns:ImportResult"/> </s:sequence> </s:complexType> <s:element name="ImportResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="ImportResult" type="tns:ArrayOfImportResult"/> </s:sequence> </s:complexType> </s:element> <s:element name="Submit"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="commands" type="tns:ArrayOfCommand"/> </s:sequence> </s:complexType> </s:element> <s:complexType name="ArrayOfContent"> <s:sequence> <s:element minOccurs="0" maxOccurs="unbounded" name="Content" nillable="true" type="tns:Content"/> </s:sequence> </s:complexType> <s:element name="SubmitResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="SubmitResult" type="tns:ArrayOfContent"/> </s:sequence> </s:complexType> </s:element> <s:element name="Login"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="name" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="password" type="s:string"/> </s:sequence> </s:complexType> </s:element> <s:complexType name="LoginResult"> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="Code" type="tns:ErrorCode"/> <s:element minOccurs="0" maxOccurs="1" name="Message" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="Session" type="s:string"/> </s:sequence> </s:complexType> <s:simpleType name="ErrorCode"> <s:restriction base="s:string"> <s:enumeration value="OK"/> <s:enumeration value="INVALID_CREDENTIALS"/> <s:enumeration value="INTERNAL_ERROR"/> <s:enumeration value="INVALID_API_VERSION"/> </s:restriction> </s:simpleType> <s:element name="LoginResponse"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="LoginResult" type="tns:LoginResult"/> </s:sequence> </s:complexType> </s:element> <s:element name="Logout"> <s:complexType/> </s:element> <s:element name="LogoutResponse"> <s:complexType/> </s:element> <s:element name="SetBusinessDate"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="date" type="s:dateTime"/> </s:sequence> </s:complexType> </s:element> <s:element name="SetBusinessDateResponse"> <s:complexType/> </s:element> <s:element name="SetLocaleName"> <s:complexType> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="localeName" type="s:string"/> </s:sequence> </s:complexType> </s:element> <s:element name="SetLocaleNameResponse"> <s:complexType/> </s:element> <s:element name="SetSchemaMode"> <s:complexType> <s:sequence> <s:element minOccurs="1" maxOccurs="1" name="mode" type="tns:SchemaMode"/> </s:sequence> </s:complexType> </s:element> <s:simpleType name="SchemaMode"> <s:restriction base="s:string"> <s:enumeration value="Basic"/> <s:enumeration value="Detailed"/> <s:enumeration value="DetailedWithHidden"/> </s:restriction> </s:simpleType> <s:element name="SetSchemaModeResponse"> <s:complexType/> </s:element> <s:complexType name="Actions"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="Cancel" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="Save" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ClearBtn" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="Scan" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModePick" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModePack" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModeShip" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModeReceive" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModePutAway" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModeItemLookup" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModeStorageLookup" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModeIssue" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModeInReceive" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModeInTransfer" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanModePhysicalCount" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanConfirm" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanRemove" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ScanQty" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="ReviewAvailability" type="tns:Action"/> <s:element minOccurs="0" maxOccurs="1" name="SaveLoc" type="tns:Action"/> </s:sequence> </s:complexType> <s:complexType name="HeaderViewServiceCommands"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="EveryWarehouse" type="tns:EveryValue"/> <s:element minOccurs="0" maxOccurs="1" name="EveryInventoryID" type="tns:EveryValue"/> <s:element minOccurs="0" maxOccurs="1" name="DeleteRow" type="tns:DeleteRow"/> <s:element minOccurs="0" maxOccurs="1" name="DialogAnswer" type="tns:Answer"/> <s:element minOccurs="0" maxOccurs="1" name="Attachment" type="tns:Attachment"/> </s:sequence> </s:complexType> <s:complexType name="HeaderView"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="Scan" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Warehouse" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="InventoryID" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Message" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Mode" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ServiceCommands" type="tns:HeaderViewServiceCommands"/> </s:sequence> </s:complexType> <s:complexType name="ItemInventorySummaryServiceCommands"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="NewRow" type="tns:NewRow"/> <s:element minOccurs="0" maxOccurs="1" name="RowNumber" type="tns:RowNumber"/> <s:element minOccurs="0" maxOccurs="1" name="DeleteRow" type="tns:DeleteRow"/> <s:element minOccurs="0" maxOccurs="1" name="DialogAnswer" type="tns:Answer"/> </s:sequence> </s:complexType> <s:complexType name="ItemInventorySummary"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="Location" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Available" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="AvailableForShipment" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="InTransit" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Expired" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="OnHand" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="BaseUnit" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="LotSerialNumber" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ExpirationDate" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ServiceCommands" type="tns:ItemInventorySummaryServiceCommands"/> </s:sequence> </s:complexType> <s:complexType name="ModeServiceCommands"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DeleteRow" type="tns:DeleteRow"/> <s:element minOccurs="0" maxOccurs="1" name="DialogAnswer" type="tns:Answer"/> <s:element minOccurs="0" maxOccurs="1" name="Attachment" type="tns:Attachment"/> </s:sequence> </s:complexType> <s:complexType name="Mode"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="Mode" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Message" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="MessageSound" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Instructions" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Prompt" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ServiceCommands" type="tns:ModeServiceCommands"/> </s:sequence> </s:complexType> <s:complexType name="ScanLogServiceCommands"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="KeyTime" type="tns:Key"/> <s:element minOccurs="0" maxOccurs="1" name="NewRow" type="tns:NewRow"/> <s:element minOccurs="0" maxOccurs="1" name="RowNumber" type="tns:RowNumber"/> <s:element minOccurs="0" maxOccurs="1" name="DeleteRow" type="tns:DeleteRow"/> <s:element minOccurs="0" maxOccurs="1" name="DialogAnswer" type="tns:Answer"/> </s:sequence> </s:complexType> <s:complexType name="ScanLog"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="Time" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Mode" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Prompt" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Scan" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Message" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ServiceCommands" type="tns:ScanLogServiceCommands"/> </s:sequence> </s:complexType> <s:complexType name="ItemServiceCommands"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DeleteRow" type="tns:DeleteRow"/> <s:element minOccurs="0" maxOccurs="1" name="DialogAnswer" type="tns:Answer"/> <s:element minOccurs="0" maxOccurs="1" name="Attachment" type="tns:Attachment"/> </s:sequence> </s:complexType> <s:complexType name="Item"> <s:sequence> <s:element minOccurs="0" maxOccurs="1" name="DisplayName" type="s:string"/> <s:element minOccurs="0" maxOccurs="1" name="ItemClass" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="Type" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="IsAKit" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ValuationMethod" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="LotSerialClass" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ProductWorkgroup" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ProductManager" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ProductManagerContact" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="BaseUnit" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="SalesUnit" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="PurchaseUnit" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="AddPopUpNote" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="PopUpNoteText" type="tns:Field"/> <s:element minOccurs="0" maxOccurs="1" name="ServiceCommands" type="tns:ItemServiceCommands"/> </s:sequence> </s:complexType> </s:schema> </wsdl:types> <wsdl:message name="ClearSoapIn"> <wsdl:part name="parameters" element="tns:Clear"/> </wsdl:message> <wsdl:message name="ClearSoapOut"> <wsdl:part name="parameters" element="tns:ClearResponse"/> </wsdl:message> <wsdl:message name="GetProcessStatusSoapIn"> <wsdl:part name="parameters" element="tns:GetProcessStatus"/> </wsdl:message> <wsdl:message name="GetProcessStatusSoapOut"> <wsdl:part name="parameters" element="tns:GetProcessStatusResponse"/> </wsdl:message> <wsdl:message name="GetScenarioSoapIn"> <wsdl:part name="parameters" element="tns:GetScenario"/> </wsdl:message> <wsdl:message name="GetScenarioSoapOut"> <wsdl:part name="parameters" element="tns:GetScenarioResponse"/> </wsdl:message> <wsdl:message name="GetSchemaSoapIn"> <wsdl:part name="parameters" element="tns:GetSchema"/> </wsdl:message> <wsdl:message name="GetSchemaSoapOut"> <wsdl:part name="parameters" element="tns:GetSchemaResponse"/> </wsdl:message> <wsdl:message name="SetSchemaSoapIn"> <wsdl:part name="parameters" element="tns:SetSchema"/> </wsdl:message> <wsdl:message name="SetSchemaSoapOut"> <wsdl:part name="parameters" element="tns:SetSchemaResponse"/> </wsdl:message> <wsdl:message name="ExportSoapIn"> <wsdl:part name="parameters" element="tns:Export"/> </wsdl:message> <wsdl:message name="ExportSoapOut"> <wsdl:part name="parameters" element="tns:ExportResponse"/> </wsdl:message> <wsdl:message name="ImportSoapIn"> <wsdl:part name="parameters" element="tns:Import"/> </wsdl:message> <wsdl:message name="ImportSoapOut"> <wsdl:part name="parameters" element="tns:ImportResponse"/> </wsdl:message> <wsdl:message name="SubmitSoapIn"> <wsdl:part name="parameters" element="tns:Submit"/> </wsdl:message> <wsdl:message name="SubmitSoapOut"> <wsdl:part name="parameters" element="tns:SubmitResponse"/> </wsdl:message> <wsdl:message name="LoginSoapIn"> <wsdl:part name="parameters" element="tns:Login"/> </wsdl:message> <wsdl:message name="LoginSoapOut"> <wsdl:part name="parameters" element="tns:LoginResponse"/> </wsdl:message> <wsdl:message name="LogoutSoapIn"> <wsdl:part name="parameters" element="tns:Logout"/> </wsdl:message> <wsdl:message name="LogoutSoapOut"> <wsdl:part name="parameters" element="tns:LogoutResponse"/> </wsdl:message> <wsdl:message name="SetBusinessDateSoapIn"> <wsdl:part name="parameters" element="tns:SetBusinessDate"/> </wsdl:message> <wsdl:message name="SetBusinessDateSoapOut"> <wsdl:part name="parameters" element="tns:SetBusinessDateResponse"/> </wsdl:message> <wsdl:message name="SetLocaleNameSoapIn"> <wsdl:part name="parameters" element="tns:SetLocaleName"/> </wsdl:message> <wsdl:message name="SetLocaleNameSoapOut"> <wsdl:part name="parameters" element="tns:SetLocaleNameResponse"/> </wsdl:message> <wsdl:message name="SetSchemaModeSoapIn"> <wsdl:part name="parameters" element="tns:SetSchemaMode"/> </wsdl:message> <wsdl:message name="SetSchemaModeSoapOut"> <wsdl:part name="parameters" element="tns:SetSchemaModeResponse"/> </wsdl:message> <wsdl:portType name="ScreenSoap"> <wsdl:operation name="Clear"> <wsdl:input message="tns:ClearSoapIn"/> <wsdl:output message="tns:ClearSoapOut"/> </wsdl:operation> <wsdl:operation name="GetProcessStatus"> <wsdl:input message="tns:GetProcessStatusSoapIn"/> <wsdl:output message="tns:GetProcessStatusSoapOut"/> </wsdl:operation> <wsdl:operation name="GetScenario"> <wsdl:input message="tns:GetScenarioSoapIn"/> <wsdl:output message="tns:GetScenarioSoapOut"/> </wsdl:operation> <wsdl:operation name="GetSchema"> <wsdl:input message="tns:GetSchemaSoapIn"/> <wsdl:output message="tns:GetSchemaSoapOut"/> </wsdl:operation> <wsdl:operation name="SetSchema"> <wsdl:input message="tns:SetSchemaSoapIn"/> <wsdl:output message="tns:SetSchemaSoapOut"/> </wsdl:operation> <wsdl:operation name="Export"> <wsdl:input message="tns:ExportSoapIn"/> <wsdl:output message="tns:ExportSoapOut"/> </wsdl:operation> <wsdl:operation name="Import"> <wsdl:input message="tns:ImportSoapIn"/> <wsdl:output message="tns:ImportSoapOut"/> </wsdl:operation> <wsdl:operation name="Submit"> <wsdl:input message="tns:SubmitSoapIn"/> <wsdl:output message="tns:SubmitSoapOut"/> </wsdl:operation> <wsdl:operation name="Login"> <wsdl:input message="tns:LoginSoapIn"/> <wsdl:output message="tns:LoginSoapOut"/> </wsdl:operation> <wsdl:operation name="Logout"> <wsdl:input message="tns:LogoutSoapIn"/> <wsdl:output message="tns:LogoutSoapOut"/> </wsdl:operation> <wsdl:operation name="SetBusinessDate"> <wsdl:input message="tns:SetBusinessDateSoapIn"/> <wsdl:output message="tns:SetBusinessDateSoapOut"/> </wsdl:operation> <wsdl:operation name="SetLocaleName"> <wsdl:input message="tns:SetLocaleNameSoapIn"/> <wsdl:output message="tns:SetLocaleNameSoapOut"/> </wsdl:operation> <wsdl:operation name="SetSchemaMode"> <wsdl:input message="tns:SetSchemaModeSoapIn"/> <wsdl:output message="tns:SetSchemaModeSoapOut"/> </wsdl:operation> </wsdl:portType> <wsdl:binding name="ScreenSoap" type="tns:ScreenSoap"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http"/> <wsdl:operation name="Clear"> <soap:operation soapAction="http://www.acumatica.com/typed/Clear" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetProcessStatus"> <soap:operation soapAction="http://www.acumatica.com/typed/GetProcessStatus" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetScenario"> <soap:operation soapAction="http://www.acumatica.com/typed/GetScenario" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="GetSchema"> <soap:operation soapAction="http://www.acumatica.com/typed/GetSchema" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SetSchema"> <soap:operation soapAction="http://www.acumatica.com/typed/SetSchema" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="Export"> <soap:operation soapAction="http://www.acumatica.com/typed/Export" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="Import"> <soap:operation soapAction="http://www.acumatica.com/typed/Import" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="Submit"> <soap:operation soapAction="http://www.acumatica.com/typed/Submit" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="Login"> <soap:operation soapAction="http://www.acumatica.com/typed/Login" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="Logout"> <soap:operation soapAction="http://www.acumatica.com/typed/Logout" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SetBusinessDate"> <soap:operation soapAction="http://www.acumatica.com/typed/SetBusinessDate" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SetLocaleName"> <soap:operation soapAction="http://www.acumatica.com/typed/SetLocaleName" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> <wsdl:operation name="SetSchemaMode"> <soap:operation soapAction="http://www.acumatica.com/typed/SetSchemaMode" style="document"/> <wsdl:input> <soap:body use="literal"/> </wsdl:input> <wsdl:output> <soap:body use="literal"/> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="Screen"> <wsdl:port name="ScreenSoap" binding="tns:ScreenSoap"> <soap:address location="http://xmysitex.com/SOAP/IN202520.asmx"/> </wsdl:port> </wsdl:service> </wsdl:definitions>
@rosenjon Try creating a graph extension for the other graph mentioned in the dynamic data source (PX.Objects.IN.InventoryItemLookupHost) as follows:
public class InventoryItemLookup2_Extension : PXGraphExtension<PX.Objects.IN.InventoryItemLookupHost> { public PXAction<InventoryItemLookup.Header> PrintItemLabel; PXButton(CommitChanges = true), PXUIField(DisplayName = "Print Item Label")] public virtual IEnumerable printItemLabel(PXAdapter adapter) { return adapter.Get(); } //optional protected void _(Events.RowSelected<InventoryItemLookup.Header> e) { PrintItemLabel.SetVisible(Base.IsMobile); } }
Yes...I already did that:
namespace AddToWMS { #region Overriding an existing graph /// <summary> ///To override or extend the behavior of an existing graph, ///derive a new class from the PXGraphExtension<T> class where T is the original graph type. /// </summary> /// public class InventoryItemMaintExtension : PXGraphExtension<PX.Objects.IN.WMS.InventoryItemLookup.Host> { public PXAction<PX.Objects.IN.InventoryItem> PrintItemLabel; [PXButton(CommitChanges = true), PXUIField(DisplayName = "Print Item Label")] public virtual IEnumerable printItemLabel(PXAdapter adapter) { return adapter.Get(); } } #endregion }
One minor difference between what you have and what I have is the object type referenced in the PXAction, but I think that doesn’t matter.
Otherwise, I really think the issue here is that my PrintItemLabel PXAction is not referenced by the WSDL file in the SOAP api reference. That is the thing I haven’t figured out how to do yet...
@rosenjon It seems there’s an error in the PXAction definition in your example:
For the PXAction, you need to define it as follows:
public PXAction<PX.BarcodeProcessing.ScanHeader> PrintItemLabel;
Notice it uses PX.BarcodeProcessing.ScanHeader instead of InventoryItem in the PXAction for the graph extension PX.Objects.IN.WMS.InventoryItemLookup.Host .
If that doesn’t work, try the last example sent and be careful about the types used in the PXAction.
@Dioris Aguilar With regards to that library (PX.BarcodeProcessing.ScanHeader), you seem to be operating with some special sauce that I don’t have. I am not able to reference that library from my Acumatica/Visual Studio environment.
@rosenjon That is for 2021R2, what is your Acumatica version?
Yeah I’m on 21.210.0030….so same I think. Maybe I haven’t activated some features in Acumatica?
@rosenjon Add this reference to your project PX.BarcodeProcessing.dll , it should be in the Bin/ folder of your instance. I am not getting any error because the example I made was done in the Customization Project screen, not using VS.
I don’t have that PX.BarcodeProcessing anywhere on my system. I don’t know why, but I also don’t think the type of the PXAction really matters here. You even posted it a different way in one of your subsequent example posts in this thread:
public PXAction<InventoryItemLookup.Header> PrintItemLabel;
What does matter is that this action gets added to the wsdl file for this page. Do you know how to do that?
@rosenjon The second example is a different graph extension. All PXAction should be defined with the type of the main DAC of the PrimaryView, otherwise they will not show up, so, you can’t put any DAC there.
First example is a graph extension for PX.Objects.IN.WMS.InventoryItemLookup.Host with main DAC PX.BarcodeProcessing.ScanHeader.
Second example is a graph extension for PX.Objects.IN.InventoryItemLookupHost with main DAC InventoryItemLookup.Header.
You sent a screenshot of this button being successfully added to the screen, so I assume you are actually building/running this code, right? If so, can you please post the output from this endpoint (obv. replace base url with whatever site you’re using)...
http://ec2-54-71-32-123.us-west-2.compute.amazonaws.com/AlaskanCopper/(W(1))/SOAP/IN202520.asmx?WSDL
Also, did you get it to work both ways, using either graph extension type?
P.S. I’m going to retry this method: public class InventoryItemMaintExtension : PXGraphExtension<PX.Objects.IN.InventoryItemLookupHost>
I had typos in my type definition….
public class InventoryItemMaintExtension : PXGraphExtension<PX.Objects.IN.WMS.InventoryItemLookup.Host>
@rosenjon Forgot we can attach files.
Here’s the customization
Ok thanks for posting that. Can you help explain this to me. Are both Graph Extensions/PXAction declarations required in order to make this work? Or did you extend both graphs because we weren’t sure which one would stick?
You said before: “Hence, the action should be defined as a graph extension of at least one of those graphs”.
Maybe you can break down a little more what’s going on here, and how I would be able to figure out which graph to extend. Also, once it is extended, then it’s as simple as adding the reference in the msdl to the ReferenceAction and ReferenceActionLink (as you showed above)?
@rosenjon Honestly speaking, trial and error: it worked in one instance with the first graph extension only and in another instance with the second. Since this screen have this DynamicDataSource attribute in the aspx, not sure how it works and when a graph defined in the TypeName works or the other.. maybe a setting or a hidden condition, not sure.
I appreciate all your help on this!
At the same time...
Honestly speaking, trial and error: it worked in one instance with the first graph extension only and in another instance with the second.
...
I’m not really sure what this means for the reliability and consistency of this code. Maybe some of the core devs from Acumatica can chime in here and help us understand what’s going on?
Honestly, this is one of the disappointing things about this platform. It is often the case that things that should be easy (because they are easy in most other coding platforms), turn out to be irrationally hard. We’re not trying to shoot the moon here. We’re trying to press a button in the mobile app that will perform the same (already working) custom action that occurs in the non-mobile app. It’s disappointing that we have to get super hacky to do that...