Financial Dimension after save is empty - axapta

I have financial dimension which contact values like BuildingID and ContractID.
When new building is created, dimension is properly filled with data. But, after that there is need for contract creation.
When contract is created there is value in financial dimension field for contractID.
But, when contract is saved, financial dimension for contract id disappear. When I check in DIMENSIONATTRIBUTEVALUESET table value for that ContractID dimension is null, there is only value for BuildingID.
I have this method for init dimensions:
void initDimensions()
{
DimensionDefault dimension;
PMGOrgDimension orgDimension;
CompanyId companyId;
PMEGround ground;
PMEBuilding building;
switch(pmcContract.EstateType)
{
case PMCEstateType::Ground :
ground = PMEGround::find(pmcContract.EstateId);
dimension = PMEObjectLegalEntity::find(ground.TableId, ground.RecId).DefaultDimension;
orgDimension = ground.OrgDimension;
companyId = ground.CompanyId;
break;
case PMCEstateType::Building :
building = PMEBuilding::find(pmcContract.EstateId);
dimension = PMEObjectLegalEntity::find(building.TableId, building.RecId).DefaultDimension;
orgDimension = building.OrgDimension;
companyId = building.CompanyId;
break;
default :
dimension = pmcContract.DefaultDimension;
orgDimension = pmcContract.OrgDimension;
companyId = pmcContract.CompanyId;
break;
}
pmcContract.DefaultDimension = dimension;
pmcContract.OrgDimension = orgDimension;
pmcContract.CompanyId = companyId;
}
Is there something what I missing ?

Try changing this line:
pmcContract.DefaultDimension = dimension;
To this:
pmcContract.DefaultDimension = DimensionDefaultingService::serviceMergeDefaultDimensions(pmcContract.DefaultDimension, dimension);

Issue is in this method:
static server public DimensionDefault tableDimension(Common _c, DimensionDefault _d)
{
DimensionAttribute dimensionAttribute;
DimensionAttributeValue dimensionAttributeValue;
DimensionAttributeSetItem dimensionAttributeSetItem;
DimensionAttributeValueSetStorage dimensionAttributeValueSetStorage;
DimensionDefault cDimensionDefault;
DimensionDefault ret;
;
ret = _d;
select firstonly RecId from dimensionAttribute
where dimensionAttribute.BackingEntityTableId == _c.TableId
join firstonly RecId from dimensionAttributeSetItem
where dimensionAttributeSetItem.DimensionAttributeSet == DimensionCache::getDimensionAttributeSetForLedger()
&& dimensionAttributeSetItem.DimensionAttribute == dimensionAttribute.RecId;
if (dimensionAttributeSetItem.RecId != 0)
{
dimensionAttributeValue = DimensionAttributeValue::findByDimensionAttributeAndEntityInst(dimensionAttribute.RecId, _c.RecId, false, true);
if (dimensionAttributeValue.RecId != 0)
{
dimensionAttributeValueSetStorage = new DimensionAttributeValueSetStorage();
dimensionAttributeValueSetStorage.addItemValues(dimensionAttributeValue.DimensionAttribute, dimensionAttributeValue.RecId, dimensionAttributeValue.HashKey);
cDimensionDefault = dimensionAttributeValueSetStorage.save();
if (cDimensionDefault != 0)
{
ret = LedgerDimensionDefaultFacade::serviceMergeDefaultDimensions(cDimensionDefault, _d);
}
}
}
return ret;
}
Merge is not working. It only takes values for _d. Not merging them.

Related

Datatables Object Reference not set to instance of an object for one variable

This is my datatables serverside implementation. FilterInput contains 5 variables:
Level <- string
Message <- string
Exception <-string
StartDate <- DateTime
EndDate <- DateTime
For some reason when I run this code as it is, I will always get this error:
{System.NullReferenceException: Object reference not set to an
instance of an object.
This is referring to this line:
data = data.Where(
u => u.Level.ToString().ToLower().Contains(FilterInput.Level.ToLower()) &&
u.Message.ToString().ToLower().Contains(FilterInput.Message.ToLower()) &&
u.Exception.ToString().ToLower().Contains(FilterInput.Exception.ToLower())
).ToList();
However, if I remove the search for FilterInput.Exception, everything runs fine again. I have tested it with input ("abc") or without input ("") and the results are the same. The other FilterInputs don't have the same error.
public JsonResult Search(SearchViewModels Input, EventLogsSearchViewModel FilterInput)
{
JsonResult result = new JsonResult(null);
try
{
var data = dbContext.EventLogs.ToList();
int totalRecords = data.Count;
var modelStructure = new Dictionary<int, string>();
modelStructure.Add(1, "Level");
modelStructure.Add(2, "TimeStamp");
modelStructure.Add(3, "LogEvent");
modelStructure.Add(4, "Message");
modelStructure.Add(5, "MessageTemplate");
modelStructure.Add(6, "Exception");
modelStructure.Add(7, "Properties");
var StartDate = FilterInput.StartDate != default(DateTime);
var EndDate = FilterInput.EndDate != default(DateTime);
if ((!string.IsNullOrEmpty(FilterInput.Level) && !string.IsNullOrWhiteSpace(FilterInput.Level)) ||
(!string.IsNullOrEmpty(FilterInput.Message) && !string.IsNullOrWhiteSpace(FilterInput.Message)) ||
(!string.IsNullOrEmpty(FilterInput.Exception) && !string.IsNullOrWhiteSpace(FilterInput.Exception)) ||
(StartDate && EndDate))
{
data = data.Where(
u => u.Level.ToString().ToLower().Contains(FilterInput.Level.ToLower()) &&
u.Message.ToString().ToLower().Contains(FilterInput.Message.ToLower()) &&
u.Exception.ToString().ToLower().Contains(FilterInput.Exception.ToLower())
).ToList();
data = data.Where(u => u.TimeStamp >= FilterInput.StartDate && u.TimeStamp <= FilterInput.EndDate).ToList();
}
if (!(string.IsNullOrEmpty(Input.Order) && string.IsNullOrEmpty(Input.OrderDir)))
{
var columnName = modelStructure.FirstOrDefault(f => f.Key == Convert.ToInt32(Input.Order));
data = data.AsQueryable().OrderBy(columnName.Value + " " + Input.OrderDir).ToList();
}
int recFilter = data.Count;
data = data.Skip(Input.StartRec).Take(Input.PageSize).ToList();
var modifiedData = data.Select(u => new EventLogsListViewModel
{
Id = u.Id,
Message = u.Message,
MessageTemplate = u.MessageTemplate,
Level = u.Level,
TimeStamp = u.TimeStamp,
Exception = u.Exception,
Properties = u.Properties,
LogEvent = u.LogEvent
});
result = this.Json(new
{
draw = Convert.ToInt32(Input.Draw),
recordsTotal = totalRecords,
recordsFiltered = recFilter,
data = modifiedData,
order = Input.Order,
orderdir = Input.OrderDir
});
}
catch (Exception e)
{
logger.LogError(e, LoggingGlobals.LoadingException);
}
return result;
}
EDIT: The exception still happens even when FilterInput.Exception is not null

How to create Query using IN?

I need to collect data and add it to temporary table in AX 2012 R3 using X++.
This is the Query on SQL
select store, receiptid, itemid, str(qty,16,0) as Qty, str(price,16,0) as Price, str(DISCAMOUNT,16,0) DiscAmount, str(taxamount,16,0) SalesTaxAmount ,convert(date, transdate) transdate, DATAAREAID from RETAILTRANSACTIONSALESTRANS
where DATAAREAID in ('5740','5760') and transdate >='2016-03-21' and transdate <='2016-03-27' and store in ('JTJDRN1','JNUSADP','JOFFICE')
and INVENTSTATUSSALES='2' and itemid in ('10010038') and receiptid in (select receiptid from RETAILTRANSACTIONPAYMENTTRANS where transdate >='2016-03-21' and transdate <='2016-03-27')
order by transdate
User can input transDate, itemid and storeid
this is what form looks like
this is my code so far
private void RetailPromoReport()
{
str receiptId, curDatetxt,fileLocation, filePath, itemtxt, startPtxt, endPtxt,
storetxt, item_txt, item2, receiptId2, rcptid_txt, store_txt, store2;
FileName fileName;
str 50 item, itemid, store;
container items, receiptid_con, stores;
int i,x, ware, itm, tot, y,z, rcptLen, storeLen;
Date emptyDate, startP, endP;
RetailTransactionPaymentTrans rtpt;
RetailTransactionSalesTrans rtst;
ReportRetailTemp rrpi_tmp, rrpi_tmp2;
QueryBuildRange qbr1, qbr2, qbr3, qbr4, qbr5;
QueryRun queryRun;
Query query, query2;
QueryBuildDataSource qbdsRetailTransactionPaymentTrans, qbdsRetailTransactionSalesTrans;
RecordInsertList recordILCRppi_tmp = new RecordInsertList(tableNum(ReportRetailTemp),false,false,false,false,false,rrpi_tmp);
;
startP = DateFrom.dateValue();
endP = DateTo.dateValue();
tot = 0;
delete_from rrpi_tmp;
while select receiptId from rtpt group by rtpt.receiptId where rtpt.transDate >= startP && rtpt.transDate <= endP
{
receiptid_con += rtpt.receiptId;
}
query = new Query();
qbdsRetailTransactionSalesTrans = query.addDataSource(tableNum(RetailTransactionSalesTrans));
qbr1 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans,TransDate));
qbr1.value(strfmt('(%3.transDate>=%1) && (%3.transDate<=%2)',Date2StrXpp(startP),Date2StrXpp(endP),qbdsRetailTransactionSalesTrans.name()));
qbr2 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans,inventStatusSales));
qbr2.value(queryValue(enum2str(RetailInventStatusSales::Posted)));
items = msCtrlCust.getSelectedFieldValues();
itemtxt = multilookupItem.valueStr();
stores = msCtrlStore.getSelectedFieldValues();
storetxt = multilookupStore.valueStr();
if(itemtxt != "")
{
item_txt = conPeek(items,1);
item2 = strFmt('(%2.itemId == "%1") ',queryValue(conPeek(items,1)),qbdsRetailTransactionSalesTrans.name());
itm = conlen(items);
if(itm > 1)
{
for (i = 2; i <= itm;i++)
{
item = conPeek(items,i);
item2 = strFmt('%1 || (%3.itemId == "%2") ',item2, queryValue(item),qbdsRetailTransactionSalesTrans.name());
}
}
qbr3 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, itemId));
qbr3.value(strFmt("%1",item2));
}
rcptLen = conlen(receiptid_con);
receiptId2 = strFmt('(%2.receiptId == "%1") ',queryValue(conPeek(receiptid_con,1)),qbdsRetailTransactionSalesTrans.name());
if(rcptLen > 1)
{
for (y = 2; y <= rcptLen; y++)
{
rcptid_txt = conPeek(receiptid_con,y);
receiptId2 = strFmt('%1 || (%3.receiptId == "%2") ',receiptId2, queryValue(rcptid_txt),qbdsRetailTransactionSalesTrans.name());
}
}
qbr4 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, receiptId));
qbr4.value(strFmt("%1",receiptId2));
if(storetxt != '')
{
store_txt = conPeek(stores,1);
store2 = strFmt('(%2.store == "%1") ',queryValue(conPeek(stores,1)),qbdsRetailTransactionSalesTrans.name());
storeLen = conlen(stores);
if(storeLen > 1)
{
for (z = 2; z <= storeLen;z++)
{
store = conPeek(stores,z);
store2 = strFmt('%1 || (%3.store == "%2") ',store2, queryValue(store),qbdsRetailTransactionSalesTrans.name());
}
}
qbr5 = qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, store));
qbr5.value(strFmt("%1",store2));
}
qbdsRetailTransactionSalesTrans.addSortField(fieldNum(RetailTransactionSalesTrans, transDate),SortOrder::Ascending);
qbdsRetailTransactionSalesTrans.addSortField(fieldNum(RetailTransactionSalesTrans, itemId),SortOrder::Ascending);
queryRun = new QueryRun(query);
while (queryRun.next())
{
rtst = queryRun.getNo(1);
rrpi_tmp.store = rtst.store;
rrpi_tmp.receiptId = rtst.receiptId;
rrpi_tmp.itemId = rtst.itemId;
rrpi_tmp.qty = rtst.qty;
rrpi_tmp.price = rtst.price;
rrpi_tmp.discAmount = rtst.discAmount;
rrpi_tmp.SalestaxAmount = rtst.taxAmount;
rrpi_tmp.transDate = rtst.transDate;
recordILCRppi_tmp.add(rrpi_tmp);
tot++;
}
ttsBegin;
recordILCRppi_tmp.insertDatabase();
ttsCommit;
ReportRetailTemp_ds.research(true);
ReportRetailTemp_ds.refresh();
if(tot > 0)
{
Box::info(strFmt("%1 row data",tot));
}
else
{
Box::info(strFmt("No Data",tot));
}
}
My code doesn't show any error in short period but because receiptId is stored in str,
receiptId2 = strFmt('%1 || (%3.receiptId == "%2") ',receiptId2, queryValue(rcptid_txt),qbdsRetailTransactionSalesTrans.name());
there is limitation and show error for long periode
Can someone make my code more efficient and
is there any way to create Query in x++ that have same function like "IN" on SQL
You have two options:
You can use more than one query range for the same field; it will automatically count as an or
for (i = conLen(items); i > 0; i--)
qbdsRetailTransactionSalesTrans.addRange(fieldNum(RetailTransactionSalesTrans, itemId)).value(queryValue(conPeek(items,i)));
You may need special handling, if the container is empty!
Often it is better to use an (exists) join instead
ds = qbdsRetailTransactionSalesTrans.addDatasource(tableNum(RetailTransactionPaymentTrans));
ds.joinMode(JoinMode::ExistsJoin);
ds.relations(true); // Or do ds.addLink(...) etc.
I am not sure I follow the correct logic here :)
If you need to do crosscompany selections, do so using the interface for that:
qbdsRetailTransactionSalesTrans.allowCrossCompany(true);
qbdsRetailTransactionSalesTrans.addCompanyRange('5740');
qbdsRetailTransactionSalesTrans.addCompanyRange('5760');

The best overloaded method match for int tryparse Error

I'm simply trying to do this, so later on when I save my values in the database they should be set to null incase the textfield is empty.
int? DeliveryAdrID = null;
int.TryParse(TextBoxDeliveryAdrID.Text, out DeliveryAdrID);
But I'm having an error parsing it along.
The above solution should later on make it possible to save empty textbox values in the database as "NULL" instead of 0.
The whole solution:
int parsedValue;
int? DeliveryAdrID = int.TryParse(TextBoxDeliveryAdrID.Text, out parsedValue) ? parsedValue : (int?)null;
int id = Convert.ToInt32(GridViewData.SelectedValue.ToString());
var data = tf.DBTable.Where(a => a.ID == id).FirstOrDefault();
if (data == null)
{
DBTable mt = new DBTable();
mt.Customer = TextBoxCustomer.Text;
mt.Country = TextBoxCountry.Text;
mt.DeliveryAdrID = parsedValue;
tf.DBTable.AddObject(mt);
tf.SaveChanges();
}
else
{
data.Customer = TextBoxCustomer.Text;
data.Country = TextBoxCountry.Text;
data.DeliveryAdrID = parsedValue;
tf.SaveChanges();
}
}
You cannot give a nullable int to int.TryParse. It must be an int. What you are trying to do can be accomplished like so:
int parsedValue;
int? DeliveryAdrID = int.TryParse(TextBoxDeliveryAdrID.Text, out parsedValue) ? parsedValue : (int?) null;

Conditional to limit .Net webservice results

I'm not sure if this is the right way but I have a web service that returns json. Now I wanted to set a conditional to omit rows returned that have a value of false in cell appearInShowcase. Most of the code is pretty straight forward what it does but the cell that has a true false value is appearInShowcase which is in a table photo. In the ms sql database the appearInShowcase is of type ntext.
public List<wsGalleryPhotos> GetGalleryPhotos(int collectionID)
{
photoDataContext dc = new photoDataContext();
List<wsGalleryPhotos> results = new List<wsGalleryPhotos>();
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo("en-US");
foreach (photo photo in dc.photos.Where(s => s.collectionID == collectionID))
{
if(photo.appearInShowcase == "true")
{
results.Add(new wsGalleryPhotos()
{
photoID = photo.photoID,
collectionID = Convert.ToInt32(photo.collectionID),
name = photo.name,
description = photo.description,
filepath = photo.filepath,
thumbnail = photo.thumbnail
});
}
}
return results;
}
if you want to add a condition, you should do it like this:
public List<wsGalleryPhotos> GetGalleryPhotos(int collectionID)
{
photoDataContext dc = new photoDataContext();
List<wsGalleryPhotos> results = new List<wsGalleryPhotos>();
System.Globalization.CultureInfo ci = System.Globalization.CultureInfo.GetCultureInfo("en-US");
results = dc.photos.Where(s => s.collectionID == collectionID && s.appearInShowcase == "true")
.Select(s => new wsGalleryPhotos
{
photoID = s.photoID,
collectionID = collectionID,
name = s.name,
description = s.description,
filepath = s.filepath,
thumbnail = s.thumbnail
}).ToList();
return results;
}

Dynamics AX 2009 X++ Selecting A Date Range

I am creating an X++ report, and the requirement is that the user can multi-select on a form and when they click the report menu button the values are pulled in based on the selection.
So far this is easy enough, and I can pull in Str ranges i.e. order numbers, item id's etc, but I want to be able to pull in a date range based on selection.
I have used a method which several MorphX reports use, with use of 3 key methods in X++ reporting;
setQuerySortOrder
setQueryEnableDS
and the main key one which is;
setQueryRange
The code for setQuery Range is as follows;
private void setQueryRange(Common _common)
{
FormDataSource fds;
LogisticsControlTable logisticsTable;
QueryBuildDataSource qbdsLogisticsTable;
QueryBuildRange qbrVanRun;
str rangeVanRun;
QueryBuildRange qbrLogId;
str rangeLogId;
QueryBuildRange qbrExpStartDate;
str rangeExpStartDate;
set vanRunSet = new Set(Types::String);
set logIdSet = new Set(Types::String);
set expStartDate = new Set(Types::Date);
str addRange(str _range, str _value, QueryBuildDataSource _qbds, int _fieldNum, Set _set = null)
{
str ret = _range;
QueryBuildRange qbr;
;
if(_set && _set.in(_Value))
{
return ret;
}
if(strLen(ret) + strLen(_value) + 1 > 255)
{
qbr = _qbds.addRange(_fieldNum);
qbr.value(ret);
ret = '';
}
if(ret)
{
ret += ',';
}
if(_set)
{
_set.add(_value);
}
ret += _value;
return ret;
}
switch(_common.TableId)
{
case tableNum(LogisticsControlTable):
qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
qbrVanRun = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, APMServiceCenterID));
qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
qbrLogId = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, LogisticsId));
// qbdsLogisticsTable = element.query().dataSourceTable(tableNum(LogisticsControlTable));
// qbrExpStartDate = qbdsLogisticsTable.addRange(fieldNum(LogisticsControlTable, APMExpDateJobStart));
fds = _common.dataSource();
for(logisticsTable = fds.getFirst(true) ? fds.getFirst(true) : _common;
logisticsTable;
logisticsTable = fds.getNext())
{
rangeVanRun = addrange(rangeVanRun, logisticsTable.APMServiceCenterID, qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMServiceCenterID), vanRunSet);
rangeLogID = addrange(rangeLogID, logisticsTable.LogisticsId, qbdsLogisticsTable, fieldNum(LogisticsControlTable, LogisticsId), logIdSet);
// rangeExpStartDate = addrange(rangeExpStartdate, logisticsTable.APMExpDateJobStart, qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMExpDateJobStart), expStartDate);
}
qbrLogId.value(rangeLogID);
qbrVanRun.value(rangeVanRun);
break;
}
}
Use queryValue to format your dates correctly for the query:
set expStartDate = new Set(Types::String);
rangeExpStartDate = addrange(rangeExpStartdate, queryValue(logisticsTable.APMExpDateJobStart), qbdsLogisticsTable, fieldNum(LogisticsControlTable, APMExpDateJobStart), expStartDate);

Resources