Shipment Screen - Line Details(allocations) on mobile giving Object Ref error - acumatica

I have exposed the Shipments screen to the mobile app.
I am now trying to add a new row in the Line Details popup area but I get an "Object reference not set to an object." error:
If I have 2 items and I allocate 1 on my PC and I can add the 2de one but pressing the +(add) button
after adding the 1st serial item to Line Details
here I was able to click the add button
Mobile code:
//Add SO302000
add screen SO302000 {
add container "ShipmentSummary"{
add layout "OrderHeader" {
displayName = "OrderHeader"
layout = "HeaderSimple"
# fields declaration
#Header
add field "ShipmentNbr"
add field "Type"
add field "Status"
add field "ShipmentDate"
add field "Customer"
add field "WarehouseID"
add field "Location"
add field "Owner"
}
add field "ShippedQuantity"
add field "ControlQuantity"
# Actions declaration
## SAVE
add recordAction "Save"{
behavior = Save
}
## CANCEL
add recordAction "Cancel" {
behavior = Cancel
}
## COPNFIRME SHIPMENT
add recordAction "ConfirmShipmentAction"
{
syncLongOperation = true
behavior = Record
}
## RELEASE FROM HOLD
add recordAction "ReleaseFromHold" {
behavior = Record
}
}
#Details
add container "Details"{
fieldsToShow = 5
#formActionsToExpand = 2
displayName = "Details"
#add group "DetailsGroup" {
#displayName = "Details
#collapsed = True
#template = ExpansionPanel
add field "InventoryID"
add field "Description"
add field "UOM"
add field "NoteText"
add field "Warehouse"
add field "ShippedQty"
add field "LotSerialNbr"
#}
}
#lineDetails
add container "LineDetails" {
################
################
BELOW IS THE ADD ROW
################
################
################
add containerAction "Insert" {
icon = "system://Plus"
behavior = Create
}
visible = True
fieldsToShow = 3
listActionsToExpand = 2
formActionsToExpand = 1
containerActionsToExpand = 2
add field "AllocWarehouse" {
selectorDisplayFormat = KeyDescription
}
add layout "AllocQtyRow" {
displayName = "AllocQtyRow"
layout = "Inline"
add field "Quantity"
add field "Allocated" {
listDisplayFormat = CaptionValue
}
}
add field "LotSerialNbr"
add layout "AllocInventoryRow" {
displayName = "AllocInventoryRow"
layout = "Inline"
add field "InventoryID" {
forceIsVisible = True
selectorDisplayFormat = KeyDescription
}
add field "Subitem"
}
add layout "AllocShipOnRow" {
displayName = "AllocShipOnRow"
layout = "Inline"
add field "ShipOn"
add field "Completed"
}
add layout "AllocShipQtyRow" {
displayName = "AllocShipQtyRow"
layout = "Inline"
add field "QtyOnShipments"
add field "QtyReceived"
}
add field "UOM"
add field "ExpirationDate"
add field "MarkForPO"
add field "RelatedDocument"
attachments {
}
}
}
To add to site map: //Update Menu
update sitemap {
add folder "Shipments"
{
type = HubFolder
displayName = "Shipments"
add Item "SO302000"
{
displayName = "Shipments"
}
}
}
I think the issue is I am missing something in the containerAction "Insert" area of my code.

Related

Field not automatically included in poline

I want to create a purchase order, the fields are not calculated : line.SiteID ; line.LineType ; line.ExpenseAcctID ; line.POAccrualAcctID
while in manual entry everything works correctly
order.OrderType = "RO";
order.Status="H";
order.BranchID=une_commandevente.BranchID;
order = poOrder.CurrentDocument.Insert(order);
order.VendorID = cmdfrs.Usrfournisseur;
order.OrderDate = DateTime.Today;
order.OrderDesc = "XXX";
order.VendorRefNbr="XXX";
poOrder.CurrentDocument.Update(order);
foreach (SOLine une_lignevente in PXSelectReadonly<SOLine,Where<SOLine.orderNbr, Equal<Required<SOLine.orderNbr>>,And<SOLine.orderType,Equal<Required<SOLine.orderType>>>>>.Select(this.Base,une_commandevente.OrderNbr,une_commandevente.OrderType))
{
var une_ligneventeext = une_lignevente.GetExtension<SOLineExt>();
if (une_ligneventeext.Usrfournisseur==cmdfrs.Usrfournisseur)
{
var line = poOrder.Transactions.Insert();
line.OrderType = "RO";
line.InventoryID = une_lignevente.InventoryID;
line.SiteID=3;
line.LineType = "NS";
line.ExpenseAcctID=39367;
line.POAccrualAcctID=39367;
line.OrderQty= une_lignevente.Qty;
line.UOM=une_lignevente.UOM;
poOrder.CurrentDocument.Update(order);
poOrder.Transactions.Update(line);
}
}
poOrder.CurrentDocument.Update(order);
poOrder.Actions.PressSave();
Thanks
Xav
There are a few adjustments needed in your logic:
For the header's cache, use the main view (Document) instead of CurrentDocument
For the header DAC, assign the Key values, then insert the row in the cache and then assign the rest of the values
For the iteration, there is no need to update the header's cache
For the grid DAC, there is no need to explicitly indicate the key values as those are defaulted from the header based on [PXDBDefault] attribute
I'd also recommend to update the cache after there is a known field that triggers events. For instance, entering the Vendor, defaults the vendor location.
Try this modified (and simplified) version:
order.OrderType = "RO";
order = poOrder.Document.Insert(order);
order.OrderDate = DateTime.Today;
order.VendorID = cmdfrs.Usrfournisseur;
poOrder.Document.Update(order);
order.BranchID=une_commandevente.BranchID;
order.OrderDesc = "XXX";
order.VendorRefNbr="XXX";
poOrder.Document.Update(order);
foreach (SOLine une_lignevente in PXSelectReadonly<SOLine,Where<SOLine.orderNbr, Equal<Required<SOLine.orderNbr>>,And<SOLine.orderType,Equal<Required<SOLine.orderType>>>>>.Select(this.Base,une_commandevente.OrderNbr,une_commandevente.OrderType))
{
var une_ligneventeext = une_lignevente.GetExtension<SOLineExt>();
if (une_ligneventeext.Usrfournisseur==cmdfrs.Usrfournisseur)
{
POLine line = new POLine();
line = poOrder.Transactions.Insert(line);
line.InventoryID = une_lignevente.InventoryID;
poOrder.Transactions.Update(line);
line.SiteID=3;
poOrder.Transactions.Update(line);
line.ExpenseAcctID=39367;
line.POAccrualAcctID=39367;
poOrder.Transactions.Update(line);
line.OrderQty= une_lignevente.Qty;
line.UOM=une_lignevente.UOM;
poOrder.Transactions.Update(line);
}
}
poOrder.Actions.PressSave();
Also, I'd recommend testing this in a fresh environment w/o customizations. Create a test button that instantiates the graph and creates a PO with a couple of lines.

How to generate the auto populated template from docusign api

I have the template setup un the sandbox. Whenever I want to be redirected to demo.docusign.net and take action on the PDF, it is auto-populating the tabs. But my requirement is to simply generate the PDF without redirecting to docusign on click of a button. I am sending user information on click of a button to docusign and it has to generate the auto populated customer data on PDF for viewing (draft version). Currently it is generating the template without any dynamic user data, even though I pass the values. Please let me know, if there is any api to perform this.
Thanks in advance
I'm not completely sure I understand what you're trying to do. But sounds like you want:
1. Remote signing. Not Embedded Signing.
2. Populate values of tabs in templates.
You also didn't specify which coding lang you used, so I'm going to give you some C#. You can find the full code examples in all langs in the links above.
// Step 1: Obtain your OAuth token
var accessToken = RequestItemsService.User.AccessToken; // Represents your {ACCESS_TOKEN}
var accountId = RequestItemsService.Session.AccountId; // Represents your {ACCOUNT_ID}
// Step 2: Construct your API headers
var config = new Configuration(new ApiClient(basePath));
config.AddDefaultHeader("Authorization", "Bearer " + accessToken);
// Step 3: Create Tabs and CustomFields
// Set the values for the fields in the template
// List item
List colorPicker = new List
{
Value = "green",
DocumentId = "1",
PageNumber = "1",
TabLabel = "list"
};
// Checkboxes
Checkbox ckAuthorization = new Checkbox
{
TabLabel = "ckAuthorization",
Selected = "true"
};
Checkbox ckAgreement = new Checkbox
{
TabLabel = "ckAgreement",
Selected = "true"
};
RadioGroup radioGroup = new RadioGroup
{
GroupName = "radio1",
// You only need to provide the readio entry for the entry you're selecting
Radios = new List<Radio> { new Radio { Value = "white", Selected = "true" } }
};
Text includedOnTemplate = new Text
{
TabLabel = "text",
Value = "Jabberywocky!"
};
// We can also add a new tab (field) to the ones already in the template
Text addedField = new Text
{
DocumentId = "1",
PageNumber = "1",
XPosition = "280",
YPosition = "172",
Font = "helvetica",
FontSize = "size14",
TabLabel = "added text field",
Height = "23",
Width = "84",
Required = "false",
Bold = "true",
Value = signerName,
Locked = "false",
TabId = "name"
};
// Add the tabs model (including the SignHere tab) to the signer.
// The Tabs object wants arrays of the different field/tab types
// Tabs are set per recipient/signer
Tabs tabs = new Tabs
{
CheckboxTabs = new List<Checkbox> { ckAuthorization, ckAgreement },
RadioGroupTabs = new List<RadioGroup> { radioGroup },
TextTabs = new List<Text> { includedOnTemplate, addedField },
ListTabs = new List<List> { colorPicker }
};
// Create a signer recipient to sign the document, identified by name and email
// We're setting the parameters via the object creation
TemplateRole signer = new TemplateRole
{
Email = signerEmail,
Name = signerName,
RoleName = "signer",
Tabs = tabs //Set tab values
};
TemplateRole cc = new TemplateRole
{
Email = ccEmail,
Name = ccName,
RoleName = "cc"
};
// Create an envelope custom field to save our application's
// data about the envelope
TextCustomField customField = new TextCustomField
{
Name = "app metadata item",
Required = "false",
Show = "true", // Yes, include in the CoC
Value = "1234567"
};
CustomFields cf = new CustomFields
{
TextCustomFields = new List<TextCustomField> { customField }
};
// Step 4: Create the envelope definition
EnvelopeDefinition envelopeAttributes = new EnvelopeDefinition
{
// Uses the template ID received from example 08
TemplateId = RequestItemsService.TemplateId,
Status = "Sent",
// Add the TemplateRole objects to utilize a pre-defined
// document and signing/routing order on an envelope.
// Template role names need to match what is available on
// the correlated templateID or else an error will occur
TemplateRoles = new List<TemplateRole> { signer, cc },
CustomFields = cf
};
// Step 5: Call the eSignature REST API
EnvelopesApi envelopesApi = new EnvelopesApi(config);
EnvelopeSummary results = envelopesApi.CreateEnvelope(accountId, envelopeAttributes);

How can I add an insert action to a grid row level on the mobile app?

I have a custom screen which has a header and detail (grid) - and there are several levels in the mobile app to navigate through to get to the tab/section with the grid. Once in the grid, I can't see a way to insert a row IF there aren't any existing rows. I've used the following code (Agenda is the container area for the grid level):
add container "Agenda" {
add field "AgendaID"
add field "Duration"
add field "AssignedTo"{
textType = PlainMultiLine
}
add field "Status"
add field "Category"
add field "Topic"{
textType = PlainMultiLine
}
add field "Comments"{
textType = PlainMultiLine
}
add field "Details"{
textType = PlainMultiLine
}
add recordAction "Save" {
behavior = Save
}
add recordAction "Cancel" {
behavior = Cancel
}
add recordAction "Delete" {
behavior = Delete
}
add recordAction "Insert" {
behavior = Create
}
}
Maybe I'm not doing this right, but the ellipse for the delete/save etc. on the bottom right doesn't show up unless there is already a row existing.
Compliments of cbetabeta (thanks much):
Add containerAction "Insert" { icon = "system://Plus" behavior = Create } add recordAction "Insert" { displayName = "Add Another" icon = "system://Plus" behavior = Create }
Also adding these at the top of your container: add container "Agenda" { fieldsToShow = 3 formActionsToExpand = 2 containerActionsToExpand = 1

How to insert an empty folder with desired name under an item in Sitecore programmatically?

I need to create empty folders in each sections (content, Layout, renderings, MediaLibrary, Templates) under Sitecore node programmatically.
Please advise.
A folder in Sitecore is a Item, with for example Template: /sitecore/templates/Common/Folder {A87A00B1-E6DB-45AB-8B54-636FEC3B5523}
So you need code to add a item:
See: How to programmatically populate Sitecore items (Add item and fields)?
https://briancaos.wordpress.com/2011/01/14/create-and-publish-items-in-sitecore/
http://learnsitecore.cmsuniverse.net/en/Developers/Articles/2009/06/ProgramaticallyItems2.aspx
For Example Under the Layout folder you can use a other Template, Template: /sitecore/templates/System/Layout/Renderings/Sublayout Folder
So there are more folder templates, and of course you can create your own, and adding the insert options you need or set a nice icoon in the standard values.
Summarized:
You need privileges to create an Sitecore item, You can use the SecurityDisabler or User Switcher.
Get the parent item.
Create the item with the template you want.
//Get the master database first
Sitecore.Data.Database masterDB = Sitecore.Configuration.Factory.GetDatabase("master");
//Creating a folder under "Renderings". Change path as per requirement
Sitecore.Data.Items.Item parentNode= masterDB.GetItem("/sitecore/layout/Renderings");
//Always get the folder template from this location
Sitecore.Data.Items.Item folder = masterDB.GetItem("/sitecore/templates/Common/Folder");
//Add the folder at desired location
parentNode.Add("Folder Name", new TemplateItem(folder));
As Jan Bluemink said:
public static Item AddFolder(String name, Item Parrent = null)
{
Database myDatabase = Sitecore.Context.Database;
if (Parrent == null)
{
return null;
}
Item kiddo = null;
try
{
Sitecore.Data.Items.TemplateItem FolderTemplate = myDatabase.GetTemplate("{EB395152-CC2F-4ECB-8FDD-DE6822517BC8}");
using (new Sitecore.SecurityModel.SecurityDisabler())
{
kiddo = Parrent.Add(name, FolderTemplate);
//Insert values in fileds
// posibly you need to change language and add version to update;
// let say a template "article with some id {00101010101010-100110-1010100-12323}" with two fiels single line text, multiline text or rich text editor
//kiddo.Editing.BeginEdit();
//try
//{
// kiddo.Fields["Title"].Value = "Title 1";
// kiddo.Fields["Description"].Value = "description 1";
// kiddo.Editing.EndEdit();
//}
//catch
//{
// kiddo.Editing.CancelEdit();
//}
}
}
catch (Exception ex) {
return null;
}
return kiddo;
}
and the call:
Item content = Sitecore.Context.Database.GetItem("/sitecore/content");
Item contentFolder = AddFolder("folder", content);
Item medialib = Sitecore.Context.Database.GetItem("/sitecore/media library/medialib");
Item medialibFolder = AddFolder("folder", medialib);

jquery-jable: How to display a field as read-only in the edit form?

I have a table pre-populated with the company LAN IP addresses with fields for associated data, status, etc. The (jquery-)jtable fields collection is configured like this.
fields: {
id: { title: 'ID'},
ip: { title: 'IP address, edit: false }
more: { ... }
}
This works but the problem is that when the edit dialog pops up the user can't see the ip address of the record being edited as jtable's edit form doesn't show the field.
I've read through the documentation but can't see any way to display a field as read-only in the edit form. Any ideas?
You don't need to hack the jTable library asset, this just leads to pains when you want to update to a later version. All you need to do is create a custom input via the jTable field option "input", see an example field setup to accomplish what you need here:
JobId: {
title: 'JobId',
create: true,
edit: true,
list: true,
input: function (data) {
if (data.value) {
return '<input type="text" readonly class="jtable-input-readonly" name="JobId" value="' + data.value + '"/>';
} else {
//nothing to worry about here for your situation, data.value is undefined so the else is for the create/add new record user interaction, create is false for your usage so this else is not needed but shown just so you know when it would be entered
}
},
width: '5%',
visibility: 'hidden'
},
And simple style class:
.jtable-input-readonly{
background-color:lightgray;
}
I have simple solution:
formCreated: function (event, data)
{
if(data.formType=='edit') {
$('#Edit-ip').prop('readonly', true);
$('#Edit-ip').addClass('jtable-input-readonly');
}
},
For dropdown make other options disabled except the current one:
$('#Edit-country option:not(:selected)').attr('disabled', true);
And simple style class:
.jtable-input-readonly{
background-color:lightgray;
}
I had to hack jtable.js. Start around line 2427. Changed lines are marked with '*'.
//Do not create element for non-editable fields
if (field.edit == false) {
//Label hack part 1: Unless 'hidden' we want to show fields even though they can't be edited. Disable the 'continue'.
* //continue;
}
//Hidden field
if (field.type == 'hidden') {
$editForm.append(self._createInputForHidden(fieldName, fieldValue));
continue;
}
//Create a container div for this input field and add to form
var $fieldContainer = $('<div class="jtable-input-field-container"></div>').appendTo($editForm);
//Create a label for input
$fieldContainer.append(self._createInputLabelForRecordField(fieldName));
//Label hack part 2: Create a label containing the field value.
* if (field.edit == false) {
* $fieldContainer.append(self._myCreateLabelWithText(fieldValue));
* continue; //Label hack: Unless 'hidden' we want to show fields even though they can't be edited.
* }
//Create input element with it's current value
After _createInputLabelForRecordField add in this function (around line 1430):
/* Hack part 3: Creates label containing non-editable field value.
*************************************************************************/
_myCreateLabelWithText: function (txt) {
return $('<div />')
.addClass('jtable-input-label')
.html(txt);
},
With the Metro theme both the field name and value will be grey colour.
Be careful with your update script that you're passing back to. No value will be passed back for the //edit: false// fields so don't include them in your update query.
A more simple version for dropdowns
$('#Edit-country').prop('disabled',true);
No need to disable all the options :)

Resources