Dynamics AX 2009: Add a field to InventJournalTrans, propagate to InventTrans - axapta

I need to add an additional field to InventJournalTrans, that after posting will show up in the InventTrans table. The field is a reference column to a record in another table. What method(s) do I need to modify to make this behavior happen?
Currently, I have already added the fields to both tables and modified the Form to allow the user to enter and save the new field. I just can't seem to find the bottom of the rabbit hole on where the actual posting to InventTrans is occurring.
Ideally, it should just be a:
inventTrans.ReasonRefRecId = inventJournalTrans.ReasonRefRecId;
assignment statement before the
inventTrans.insert();
call. Anybody have a clue on where this is at?

The link above does contain the solution -- I have included the code from that page in case that page disappears or no longer becomes available. Thanks to gl00mie for answering on that site and providing this answer.
You should create a new InventMovement method like this:
public MyNewFieldType myNewField()
{
return MyNewFieldType::DefaultValue; // suppose your new field is an enum
}
Then modify \Classes\InventMovement\initInventTransFromBuffer
void initInventTransFromBuffer(InventTrans _inventTrans, InventMovement _movement_orig)
{
// ... append this line to the end of whatever else is already in this method
_inventTrans.MyNewField = this.myNewField();
}
And finally overload the new method in the InventMov_Journal class:
public MyNewFieldType myNewField()
{
return inventJournalTrans.MyNewField;
}

Related

How do I get data from a related user in a subclass of ParseObject?

I'm working in VisualStudio on a Xamarin project.
I have a ParseObject subclass. It has a field "SentBy" that links to a ParseUser. It's constructed like this:
[ParseClassName("Beacon")]
public class Stuff_ParseBeacon : ParseObject
{
public Stuff_ParseBeacon() { }
[ParseFieldName("sentBy")]
public ParseUser SentBy
{
get { return GetProperty<ParseUser>(); }
set { SetProperty(value);}
}
}
I'm trying to include a parameter that doesn't need to be in the ParseClass on the server, which gets the data stored under "phoneNumber" from the linked user. So, like this:
public string SentByPhoneNumber
{
get
{
return SentBy.Get<string>("phoneNumber");
}
}
But I keep getting the error that there's no such key in that ParseUser--which is false, because all my ParseUsers store a phone number.
What am I doing wrong?
(BTW, in case it matters: I'm trying to use SentByPhoneNumber as a bindable property)
I don't think this is the best way to do it, but this is what I ended up doing.
I just added a phoneNumber field to the Beacon class, and it gets directly filled by the user who creates the Beacon--the user who gets stored in the SentBy field.
The problem with this is that the won't automatically update if I change the phoneNumber on the SentBy user.
This is pretty much exactly what I didn't want to do in my question.
So I'm sure there's a better way to refer to a field on a stored user than manually putting that data in the referring class at the time of creation, but it's what I've had to do to move on.

Change width of a lookup column

I've created a lookup with two columns, first one containing and integer which works just fine but the second one has a long name and this is where the problem arises. Users should horizontally scroll in order to check the entire string and even in that case, the column's width is not big enough to display the whole data.
I've found this :
Adjusting column width on form control lookup
But i don't understand exactly where and what to add.
I am not sure but maybe I have to add the fact that this lookup is used on a menu item which points to an SSRS report, in the parameters section.
Update 1:
I got it working with a lookup form called like this :
Args args;
FormRun formRun;
;
args = new Args();
args.name(formstr(LookupOMOperatingUnit));
args.caller(_control);
formRun = classfactory.formRunClass(args);
formRun.init();
_control.performFormLookup(formRun);
and in the init method of this form i added:
public void init()
{
super();
element.selectMode(OMOperatingUnit_OMOperatingUnitNumber);
}
meaning the field i really need.
I am not sure i understand the mechanism completely but it seems it knows how to return this exact field to the DialogField from where it really started.
In order to make it look like a lookup, i have kept the style of the Design as Auto but changed the WindowType to Popup, HideToolBar to Yes and Frame to Border.
Probably the best route is do a custom lookup and change the extended data type of the key field to reflect that. In this way the change is reflected in all places. See form FiscalCalendarYearLookup and EDT FiscalYearName as an example of that.
If you only need to change a single place, the easy option is to override performFormLookup on the calling form. You should also override the DisplayLength property of the extended data type of the long field.
public void performFormLookup(FormRun _form, FormStringControl _formControl)
{
FormGridControl grid = _form.control(_form.controlId('grid'));
grid.autoSizeColumns(false);
super(_form,_formControl);
}
This will not help you unless you have a form, which may not be the case in this report scenario.
Starting in AX 2009 the kernel by default auto-updates the control sizes based on actual record content. This was a cause of much frustration as the sizes was small when there was no records and these sizes were saved! Also the performance of the auto-update was initially bad in some situations. As an afterthought the grid control autoSizeColumns method was provided but it was unfortunately never exposed as a property.
you can extends the sysTableLookup class and override the buildFromGridDesign method to set the grid control width.
protected void buildFormGridDesign(FormBuildGridControl _formBuildGridControl)
{
if (gridWidth > 0)
{
_formBuildGridControl.allowEdit(true);
_formBuildGridControl.showRowLabels(false);
_formBuildGridControl.widthMode(2);
_formBuildGridControl.width(gridWidth);
}
else
{
super(_formBuildGridControl);
}
}

How to determine which field has been updated?

What's the correct way to determine which field has been changed in update() method on a table?
I know it's possible in modifiedField() via fieldId but that's too early.
The method you are looking for is Orig()
Look in the update() method of BOMTable or BankAccountTrans
The table has a method called orig that exposes the values of the last saved state of the current record.
a good example and description can be found here
http://msdax.blogspot.co.uk/2007/07/programming-of-basic-methods-of-tables.html
void update () {
CustTable this_Orig = this.orig ();
;
if (this_Orig.custGroup! = this.custGroup)
{
//Cust group is changing on this update
}
...

Vaadin databinding between ListSelect and java.util.List<String>

I am new to vaadin and have a databinding problem. I have posted allready in the vaadin forum, but no answer up to now.
if you answer here, I will of course reward it anyway.
https://vaadin.com/forum/-/message_boards/view_message/1057226
thanks in advance.
greets,
Andreas
Additional information: I tried allready to iterate over the items in the container, after pressing a save button. After deleting all original elements in the model collection, and adding copies from the container, the GUI breaks. Some other GUI elements do not respond anymore.
I have personally never used ListSelect, but I found this from the API docs:
This is a simple list select without, for instance, support for new items, lazyloading, and other advanced features.
I'd recommend BeanItemContainer. You can use it like this:
// Create a list of Strings
List<String> strings = new ArrayList<String>();
strings.add("Hello");
// Create a BeanItemContainer and include strings list
final BeanItemContainer<String> container = new BeanItemContainer<String>(strings);
container.addBean("World");
// Create a ListSelect and make BeanItemContainer its data container
ListSelect select = new ListSelect("", container);
// Create a button that adds "!" to the list
Button button = new Button("Add to list", new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
container.addBean("!");
}
}
// Add the components to a layout
myLayout.addComponent(button);
myLayout.addComponent(select);
The downside (or benefit, it depends :) of this is that you can't add duplicate entries to a BeanItemContainer. In the example above the exclamation mark gets only added once.
You can get a Collection of Strings by calling:
Collection<String> strings = container.getItemIds();
If you need to support duplicate entries, take a look at IndexedContainer. With IndexedContainer you can add a String property by calling myIndexedContainer.addContainerProperty("caption", String.class, ""); and give each Item a unique itemId (or let the container generate the id's automatically).
Im not sure I understand your problem but I belive that it might be that you haven't told the controller to repaint. You do this be setting the datasource like this after the save event has occured.
listSelect.setContainerDataSource(listSelect.getContainerDataSource());

copy a Collection element by value in C#

In the code below, a reference type is being added. How can i do this value type?
imgList.Items.Add(imgList.Items[0]);
imgList.Items[imgIndex].Data = input; <== **This updates the 0th and the newly added element which is the issues**
Please advise
In order to avoid this issue, you need to clone imgList.Items[0] before adding it to imgList.Items. This basically involves creating a new object of the same type and populating it with data from the original.
The complexity of doing so depends on what the object is, but look at the answers to this question for some tips on cloning objects.
Edit: I forgot that .MemberwiseClone was protected.
You don't say in your code what the type of object is that you're adding to the list. If it's a class of yours, you can add a method to return a copy:
public MyType ShallowCopy()
{
return (MyType)this.MemberwiseClone();
}
and use
imgList.Items.Add(imgList.Items[0].ShallowCopy());
Or you can add a copy constructor:
public MyType(MyType original)
{
// Copy each of the properties from original
this.Data = original.Data;
}
and use
imgList.Items.Add(new MyType(imgList.Items[0]));

Resources