RDD Calculated Fields, a black box?

I think I read logic to populate calculated fields in OOTB RDDs is a black box.

Is that so?

For example, in effort to figure out why this line prints conditionally in ARForm:

we find it’s based on a calculated field called Calc_LineSoldToAddressList

Okay, well why does it print on some invoices but not others?
Some invoices have a value in that field and some don’t.
Okay why?

That’s where I’m stuck.

You would have to get a copy of the dll for that report and decompile it.

3 Likes

So it’s a black box now but will get blacker once Classic it gone as us SaaS customers won’t really have access --at least for current release-- to the DLLs anymore.

Note to self: Keep copies of 25.2 DLLs for future reference needs.

6 Likes

So perhaps better to just ask for anyones insights into specific cases.

Anyone know what drives this? Could it be Customer BillTo Name doesn’t equal Customer Name?

InvcHead address list:

	private void GetInvcHeadSoldToAddressList(out string cAddrList)
	{
		cAddrList = string.Empty;
		string[] Addr = new string[8];
		string tmp_name = string.Empty;
		string tmp_address1 = string.Empty;
		string tmp_address2 = string.Empty;
		string tmp_address3 = string.Empty;
		string tmp_city = string.Empty;
		string tmp_state = string.Empty;
		string tmp_zip = string.Empty;
		_ = string.Empty;
		int tmp_countrynum = 0;
		string tmp_formatstr = string.Empty;
		Customer altCustomer = null;
		if (InvcHead != null)
		{
			altCustomer = Customer.FindFirstByPrimaryKey(Db, InvcHead.Company, InvcHead.SoldToCustNum);
		}
		if (altCustomer != null)
		{
			tmp_name = altCustomer.Name;
			tmp_address1 = altCustomer.Address1;
			tmp_address2 = altCustomer.Address2;
			tmp_address3 = altCustomer.Address3;
			tmp_city = altCustomer.City;
			tmp_state = altCustomer.State;
			tmp_zip = altCustomer.Zip;
			_ = altCustomer.Country;
			tmp_countrynum = altCustomer.CountryNum;
			tmp_formatstr = altCustomer.FormatStr;
			if (!string.IsNullOrEmpty(altCustomer.BTName))
			{
				tmp_name = altCustomer.BTName;
				tmp_address1 = altCustomer.BTAddress1;
				tmp_address2 = altCustomer.BTAddress2;
				tmp_address3 = altCustomer.BTAddress3;
				tmp_city = altCustomer.BTCity;
				tmp_state = altCustomer.BTState;
				tmp_zip = altCustomer.BTZip;
				_ = altCustomer.BTCountry;
				tmp_countrynum = altCustomer.BTCountryNum;
				tmp_formatstr = altCustomer.BTFormatStr;
			}
			FormatAddr.RunFormatAddr(tmp_name, tmp_address1, tmp_address2, tmp_address3, tmp_city, tmp_state, tmp_zip, tmp_countrynum, tmp_formatstr, out Addr[0], out Addr[1], out Addr[2], out Addr[3], out Addr[4], out Addr[5], out Addr[6], out Addr[7]);
			cAddrList = Addr[0] + "~" + Addr[1] + "~" + Addr[2] + "~" + Addr[3] + "~" + Addr[4] + "~" + Addr[5] + "~" + Addr[6] + "~" + Addr[7];
		}
	}

InvcDtl address list:

	private void GetDtlAddressList(out string cAddrList)
	{
		cAddrList = string.Empty;
		string[] Addr = new string[8];
		string tmp_name = string.Empty;
		string tmp_address1 = string.Empty;
		string tmp_address2 = string.Empty;
		string tmp_address3 = string.Empty;
		string tmp_city = string.Empty;
		string tmp_state = string.Empty;
		string tmp_zip = string.Empty;
		_ = string.Empty;
		int tmp_countrynum = 0;
		string tmp_formatstr = string.Empty;
		Customer altCustomer = null;
		if (InvcDtl != null)
		{
			altCustomer = Customer.FindFirstByPrimaryKey(Db, InvcHead.Company, InvcDtl.CustNum);
		}
		if (altCustomer != null)
		{
			tmp_name = altCustomer.Name;
			tmp_address1 = altCustomer.Address1;
			tmp_address2 = altCustomer.Address2;
			tmp_address3 = altCustomer.Address3;
			tmp_city = altCustomer.City;
			tmp_state = altCustomer.State;
			tmp_zip = altCustomer.Zip;
			_ = altCustomer.Country;
			tmp_countrynum = altCustomer.CountryNum;
			tmp_formatstr = altCustomer.FormatStr;
			if (!string.IsNullOrEmpty(altCustomer.BTName))
			{
				tmp_name = altCustomer.BTName;
				tmp_address1 = altCustomer.BTAddress1;
				tmp_address2 = altCustomer.BTAddress2;
				tmp_address3 = altCustomer.BTAddress3;
				tmp_city = altCustomer.BTCity;
				tmp_state = altCustomer.BTState;
				tmp_zip = altCustomer.BTZip;
				_ = altCustomer.BTCountry;
				tmp_countrynum = altCustomer.BTCountryNum;
				tmp_formatstr = altCustomer.BTFormatStr;
			}
			FormatAddr.RunFormatAddr(tmp_name, tmp_address1, tmp_address2, tmp_address3, tmp_city, tmp_state, tmp_zip, tmp_countrynum, tmp_formatstr, out Addr[0], out Addr[1], out Addr[2], out Addr[3], out Addr[4], out Addr[5], out Addr[6], out Addr[7]);
			cAddrList = Addr[0] + "~" + Addr[1] + "~" + Addr[2] + "~" + Addr[3] + "~" + Addr[4] + "~" + Addr[5] + "~" + Addr[6] + "~" + Addr[7];
		}
	}

Also, GetDtlAddressList is called conditionally, checking InvcHead.Consolidated == true, and that the invoice detail is against a CustNum:

string[] firstOfFields = new string[1] { "CustNum" };
foreach (InvcDtl InvcDtl_iterator in (IEnumerable<InvcDtl>)listwrapper)
		{ ...
                bool num = listwrapper.FirstOf(firstOfFields);
			if (num && InvcHead.Consolidated)
			{
				GetDtlAddressList(out LineSoldToAddressList);
			}
            ... }

And, FormatAddr.RunFormatAddr:

public void RunFormatAddr(string CorpName, string Address1, string Address2, string Address3, string City, string State, string Zip, int CountryNum, string AddrString, out string TempAdd1, out string TempAdd2, out string TempAdd3, out string TempAdd4, out string TempAdd5, out string TempAdd6, out string TempAdd7, out string TempAdd8)
{
	TempAdd1 = string.Empty;
	TempAdd2 = string.Empty;
	TempAdd3 = string.Empty;
	TempAdd4 = string.Empty;
	TempAdd5 = string.Empty;
	TempAdd6 = string.Empty;
	TempAdd7 = string.Empty;
	TempAdd8 = string.Empty;
	int count = 0;
	int SubCount = 0;
	string AddrStrEle = string.Empty;
	_ = string.Empty;
	string[] TempAddr = new string[9];
	for (int aidx = 0; aidx < TempAddr.Length; aidx++)
	{
		TempAddr[aidx] = string.Empty;
	}
	int ArIndex = 1;
	string CountryDesc = string.Empty;
	string v_AllDelimChar = string.Empty;
	Country = FindFirstCountry(base.Session.CompanyID, CountryNum);
	if (Country != null)
	{
		AddrString = ((AddrString.Length == 0) ? Country.FormatStr : AddrString);
		CountryDesc = Country.Description;
	}
	v_AllDelimChar = ((AddrString.Length > 0) ? "~".PadRight(AddrString.Length + "~".Length, Convert.ToChar("~")) : null);
	if (AddrString.Length == 0 || AddrString.Compare(v_AllDelimChar) == 0)
	{
		AddrString = "<CP>~<A1>~<A2>~<A3>~<CT>`<ST>`<ZP>~<CR>";
	}
	for (count = 1; count <= AddrString.Split(Convert.ToChar("~")).Length; count++)
	{
		AddrStrEle = AddrString.Entry(count - 1, "~");
		if (AddrStrEle.Split(Convert.ToChar("`")).Length > 1)
		{
			for (SubCount = 1; SubCount <= AddrStrEle.Split(Convert.ToChar("`")).Length; SubCount++)
			{
				switch (AddrStrEle.Entry(SubCount - 1, "`").ToUpperInvariant())
				{
				case "<CP>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + CorpName;
					break;
				case "<A1>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Address1;
					break;
				case "<A2>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Address2;
					break;
				case "<A3>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Address3;
					break;
				case "<CT>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + City;
					break;
				case "<ST>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + State;
					break;
				case "<ZP>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Zip;
					break;
				case "<CR>":
					TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + CountryDesc;
					break;
				}
			}
		}
		else
		{
			switch (AddrStrEle.ToUpperInvariant())
			{
			case "<CP>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + CorpName;
				break;
			case "<A1>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Address1;
				break;
			case "<A2>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Address2;
				break;
			case "<A3>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Address3;
				break;
			case "<CT>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + City;
				break;
			case "<ST>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + State;
				break;
			case "<ZP>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + Zip;
				break;
			case "<CR>":
				TempAddr[ArIndex - 1] = TempAddr[ArIndex - 1] + " " + CountryDesc;
				break;
			}
		}
		if (AddrStrEle.Length > 0 && string.IsNullOrWhiteSpace(TempAddr[ArIndex - 1]))
		{
			ArIndex--;
		}
		ArIndex++;
	}
	TempAdd1 = TempAddr[0].Trim();
	TempAdd2 = TempAddr[1].Trim();
	TempAdd3 = TempAddr[2].Trim();
	TempAdd4 = TempAddr[3].Trim();
	TempAdd5 = TempAddr[4].Trim();
	TempAdd6 = TempAddr[5].Trim();
	TempAdd7 = TempAddr[6].Trim();
	TempAdd8 = TempAddr[7].Trim();
}
1 Like

Thanks Gabe. That’s a lot to digest but I think I gather the key is this line:

if (!string.IsNullOrEmpty(altCustomer.BTName))

Some Customers have this and others don’t. Those that do have a value in the RDD field and print that line on the report. Even though the Customer, thus BTName, does not differ across all lines. Seems like the intent would be to print only if it’s different. :man_shrugging:

EDIT: I wonder if this is a bug introduced with the relatively recent Consolidated Milestone Billing option on the Customer record. This ARInv is an ADV Milestone billing marked consolidated.

1 Like

Does anyone know what drives InvHead.Consolidated? I know about Consolidated Milestone Billings but not familiiar enough with all AR options to know if there are other ‘consolidated’ types.

More like as dark as antimatter, whatever colour that is :grin:

1 Like