How to display a price if found and another if not found? AX 2012 - axapta

I have two tables created by me. I created a form for the second table. I have to add testing data to the form so the Price field will be populated automatically based on the following logic:
check if the ItemId is available in the first Table
If found, display the price of the item from the first table
If not found, display the standard price of the item (Product information management/ Common > Relased products, select a product and on Sell Tab > Price unit.
I tried the following display method but when I choose the ItemId it shows me only 1 or only the first table value and the rest Items which are not found the value 0.
display Price price()
{
HC_ClubAxEx1 hcex1;
InventTableModule inventTableModule;
select PriceUnit from inventTableModule;
if (this.ItemId == hcex1.ItemId)
{
this.Price = hcex1.Price;
select Price from hcex1;
}
else
{
this.Price = inventTableModule.PriceUnit;
}
return this.Price;
}
Please help

In my opinion you need to check the display method:
This command, return always the first value:
select PriceUnit from inventTableModule;
display Price price()
{
HC_ClubAxEx1 hcex1;
InventTableModule inventTableModule;
// In the same way you need to select hcex1 Table by query:
//Example:
select hcex1 where hcex1.MyField == 'yourValue...'
if (this.ItemId == hcex1.ItemId)
{
// Try to check in debug mode, if the current hcex1 record follow your logic
this.Price = hcex1.Price;
// The below code line it's not necessary for you.
//Need to select the record before to use it
//select Price from hcex1;
}
else
{
// select PriceUnit from inventTableModule;
// You need to create a right select
//Example below:
// Need to select the record by
//current ItemId or by your logic.
select PriceUnit from inventTableModule
where inventTableModule.ItemId == this.ItemId;
this.Price = inventTableModule.PriceUnit;
}
return this.Price;
}
Following the other people, I try to recommend you to read these guides:
https://learn.microsoft.com/en-us/dynamicsax-2012/developer/select-statement-syntax
https://dynamicsaxswapt.wordpress.com/2015/10/01/select-statements-in-ax-2012/
https://learn.microsoft.com/en-us/dynamicsax-2012/developer/select-statement-examples
Have a nice day.

Related

How to bind select query as datasource in report?

I have a select statement that I want to bind as data source in a report.
I have not found a way to design an appropriate AOT query.
This is how it looks like in X++
public void insertData(date data = today())
{
BHNEmployeesOnDay ins;
EmplTable tbl;
CompanyInfo info;
BHNEmplAgreements Agreemnt;
BHNEmplAgreements Agreemnt2;
BHNEMPLHISTORYCOMPANY history;
BHNEMPLHISTORYCOMPANY history_test;
BHNDIVISIONTABLE division;
BHNPOSITIONTABLE position;
SysCompanyUserInfo sys1;
SysUserInfo sys2;
UserInfo usrInfo;
Date infinity = mkdate(1,1,1900);
;
delete_from ins;
while select * from tbl
join Info where info.dataAreaId == tbl.dataAreaId && info.BLX_companyForDW == 1
join sys1 where sys1.EmplId==tbl.EmplId && sys1.dataAreaId == tbl.dataAreaId
join sys2 where sys1.UserId==sys2.Id
join usrInfo where usrInfo.id==sys1.UserId
exists join history_test
where history_test.EmplId==tbl.EmplId && history_test.dataAreaId==tbl.dataAreaId
join Agreemnt where Agreemnt.HistoryId==history_test.HistoryId
&& (agreemnt.DateTo >= data || agreemnt.DateTo==infinity)
{
select firstonly *
from history order by history.DateFrom desc, Agreemnt2.DateFrom desc
where history.EmplId==tbl.EmplId && history.dataAreaId==tbl.dataAreaId
join Agreemnt2 where Agreemnt2.HistoryId==history.HistoryId
&& Agreemnt2.DateFrom<=data && (Agreemnt2.DateTo >= data || Agreemnt2.DateTo==infinity)
join division where division.DivisionId==agreemnt.DivisionId
join position where position.PositionId==agreemnt.PositionId;
ins.adddRecord(tbl.EmplId, tbl.Name_BHN, tbl.BirthDate, division.Name, position.FullName);
}
}
Currently I generate data into a table [during run() method of the report], then simply select from that table. So far only 1 person uses this report so it's not a problem, but if two people run the same report simultaneously, I'm gonna get dirty reads.
I know it's bad approach, but I'm out of ideas. I thought of making a View on T-SQL side and try to select from it - but I was told that it might not be detected or simply not transferred to other instances of our AX during export, so it has to be done on AX side.
How can I solve this?
Just in case this is query in T-SQL SQL query on pastebin
You could overwrite the report's fetch method and just use your X++ code as is to get the records and then use the report's send method to process them.
See here for an example.
The example uses a query object but you could easily swap that with your own X++ code - you just eventually have to call send for the records you want to be processed by the report.
Update:
For example you could just fetch any record of SalesTable and call send.
In this example a member variable salesTable is assumed so that you can access the current record in a display method in case you need it.
public boolean fetch()
{
boolean ret;
//ret = super();
;
select firstOnly salesTable;
this.send(salesTable);
return true;
}

Pass a value from a form to a method in a view

I have a View with a data source of the shipment table. This view has a method that contains a query. This query takes a shipment id and returns the sales id from the sales line table for this shipment. This view has a computed field that is the output of the query. The computed field is then used on a form.
If I hard code the shipment id the process works correctly. My question is how do I get the shipment id dynamically from a list of shipment ids. For instance, I have a form that lists all shipments. I want to place a field next to the shipment id that contains the calculated sales id from the process above.
Bottom line: I want the first column of a grid to be a shipment id and the second column to be the sales id for the shipment in the first column.
This is an example of the method described above that contains the query:
private static server str findSalesLine()
{
WMSShipment wmsShipment;
WMSOrderTrans wmsOrderTrans;
SalesLine salesLine;
select wmsShipment
join wmsOrderTrans
where wmsShipment.shipmentId == '1040383'
&& wmsShipment.shipmentId == wmsOrderTrans.shipmentId
join salesId from salesLine
where salesLine.LineNum == wmsOrderTrans.inventTransRefLineNum
&& salesLine.SalesID == wmsOrderTrans.inventTransRefID
&& salesLine.ExternalItemId != '';
return salesLine.SalesId;
}
I would use a computed column similar to the below. I'm in a different environment than you so the SQL is not valid on my box but it should work on yours.
Add a new string computed column to your view, then set this method as the datamethod.
public static server str getSalesId()
{
tableName viewName = tableStr(testView);//name of your view
DataSourceName wmsShipmentDsName = identifierStr(WMSShipment);//change if your dsname is different on your view
str returnStr;
returnStr =
" SELECT G1.SALESID FROM SALESLINE G1 " + //don't use "T1 T2" etc as aliases on computed columns
" JOIN WMSORDERTRANS G2 ON " +
" G1.LINENUM = G2.INVENTTRANSREFLINENUM AND " +
" G1.SALESID = G2.INVENTTRANSREFID AND " +
" SALESLINE.EXTERNALITEMID <> '' " +
" WHERE G2.SHIPMENTID == " +
SysComputedColumn::returnField(viewName, wmsShipmentDsName, fieldStr(WMSShipment, ShipmentId));
return returnStr;
}
I think what you're looking for is a query range (https://msdn.microsoft.com/en-us/library/aa638454.aspx) or a display method (https://msdn.microsoft.com/en-us/library/aa595058.aspx)
Do you have any more detail or sample code?

Check field value through 2 methods

I have a Report which i want to check on if a certain field on the SalesLine table is filled, if so, show the value of this field.
I have 2 custom tables which the report is using.
Table A & Table B
Table A, has a method with the following query:
select firstonly Id from TableB
where TableB.Id == this.Id;
return TableB.Id;
Table B, has a method with the following code:
public SalesLine salesLine()
{
return SalesLine::findInventTransId(this.InventTransId);
}
Now I need to check on the report, throughout these 2 methods, if Field X on the Sales Line table is filled. How can I accomplish this?
Modify table A method as below.
select firstonly Id,InventTransId from TableB where TableB.Id == this.Id;
return TableB.salesLine().Fieldx ? TableB.Id : 0 ;
The answer to your question seems to obvious to me...so maybe you're not asking your question correctly:
if(TableB.salesLine().FieldX)
info("FieldX is filled");

Perform method action based on duplicate values

I have a table, which i am creating a method on, i want run on action based on duplicatie values from 2 fields.
For example:
I have Table A which contains these fields:
IncidentDescription
Identifier
Now i want to run a certain action in the method based on the following criteria:
If the IncidentDescription already exists in another row in the same table, but only if the Identifier is different. (So it doesn't run the action if only 1 line with the IncidentDescription exists)
How can i solve this? Is it possible to accomplish this in an if statement?
Or is there a possibility/is it better to run a "while select" query, and (if it exists) run a count method based on the count result (>1).
EDIT:
I am trying to create the query as following:
select count (IncidentDescription) from TableA;
{
// I am trying to convert the result, because it gives me the error: "Operand types are not compatible with the operator, i am not sure how to make this.
serialCount = str2num(IncidentDescription);
if (IncidentDescription > 1)
//Action to go here;
}
I will build in the Identifier later.
Please use the following code as a hint and modify it according to your requirements:
TableA tableA;
TableA tableAJoin;
;
select firstOnly tableA
join tableAJoin
where tableA.IncidentDescription == tableAJoin.IncidentDescription
&& tableA.Identifier != tableAJoin.Identifier;
if (tableA.RecId)
{
info(strFmt("%1 - %2", tableA.Identifier, tableA.IncidentDescription));
info(strFmt("%1 - %2", tableAJoin.Identifier, tableAJoin.IncidentDescription));
}
If you need this check for displayOption method on a form datasource (where tableA is a datasource name), then modify it as follows
public void displayOption(Common _record, FormRowDisplayOption _options)
{
TableA tableACurrent;
TableA tableALocal;
;
tableACurrent = _record;
select firstOnly RecId from tableALocal
where tableALocal.IncidentDescription == tableACurrent.IncidentDescription
&& tableALocal.Identifier != tableACurrent.Identifier;
if (tableALocal.Identifier)
{
//record has dublicates
...
}
super(_record, _options);
}

How to not update ValidFrom - ValidTo table field?

I have to update a record on Table with ValidTimeStateFieldType UTCDateTime, but I need to Update only a string field.
If I use this code:
while select forUpdate MyTable
{
MyTable.StringField = "Test";
MyTable_UPD.validTimeStateUpdateMode(ValidTimeStateUpdate::EffectiveBased);
ttsbegin;
MyTable.update();
ttscommit;
}
After command MyTable.update(); change the value on table MyTable.ValidFrom or MyTable.ValidTo.
I need to change only the value on StringField, I don't need to change the values on ValidFrom/To. I want to preserve the same information on UTC field and I don't want to create a new record.
If I use MyTable.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction); I receive an error.
It's possible to change only value and don't touch anything on ValueFrom/To field?
Thanks,
enjoy!
If I am not mistaken it is not possible to modify only your StringField because in your table in Indexes you have defined DateTime field.
You need use validTimeStateUpdateMode function, in your code use MyTable and then MyTable.update() but you use validTimeStateUpdateMode(ValidTimeStateUpdate::EffectiveBased);
in MyTable_UPD not MyTable.
Try This:
ttsbegin;
while select forUpdate MyTable
{
MyTable.StringField = "Test";
MyTable.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);
MyTable.update();
}
ttscommt;
Try using a valid time state range in your select statement.
Something like this:
MyTable.validTimeStateUpdateMode(ValidTimeStateUpdate::Correction);
ttsbegin;
while select forUpdate validTimeState(1\1\1900, 31\12\2154) * from MyTable
{
MyTable.StringField = "Test";
MyTable.update();
}
ttscommit;
I used examples from this MSDN page for help: https://msdn.microsoft.com/en-us/library/gg843767.aspx

Resources