SQL View to get complex data but for which company - acumatica

I have created a SQL view to get complex data based on some calculations. Now I am using these view to create GI. However, while viewing GI result, it is showing me data for all companies irrespective of which company I am logged into.
Here is the SQL view I have created-
CREATE VIEW [dbo].[vw_View1]
AS
SELECT CompanyID,
OrderNbr,
OrderType,
SUM(BodyCost) AS BodyCost,
SUM(TruckCost) AS TruckCost,
SUM(CostOfParts) AS CostOfParts,
SUM(CostOfLabour) AS CostOfLabour,
SUM(CostOfSub) AS CostOfSub,
SUM(GrossSale) AS GrossSale,
SUM(FET) AS FET,
SUM(TireCredit) as TireCredit,
SUM(LabourHours) AS LabourHours,
InvoiceNbr
FROM
(
SELECT
/* 00 */ so.CompanyID,
/* 00 */ so.OrderNbr,
/* 00 */ so.OrderType,
/* 05 */ CASE WHEN (ic.ItemClassID = '030')
OR (ic.ItemClassID = '040')
OR (ic.ItemClassID = '050')
OR (ic.ItemClassID = '060')
OR (ic.ItemClassID = '061')
OR (ic.ItemClassID = '070')
OR (ic.ItemClassID = '080')
OR (ic.ItemClassID = '090')
OR (ic.ItemClassID = '100')
THEN SUM(sol.UsrUserDefinedCost * sol.OrderQty)
END AS BodyCost,
/* 35 */ CASE WHEN (ic.ItemClassID = '110')
OR (ic.ItemClassID = '111')
THEN SUM(sol.OrderQty)
END AS LabourHours
FROM SOOrder so
LEFT JOIN SOLine sol ON so.OrderType = sol.OrderType AND so.OrderNbr = sol.OrderNbr and so.CompanyID = sol.CompanyID
LEFT JOIN InventoryItem inv ON sol.InventoryID = inv.InventoryID and sol.CompanyID = inv.CompanyID
LEFT JOIN INItemClass ic ON inv.ItemClassID = ic.ItemClassID and inv.CompanyID = ic.CompanyID
WHERE so.CompanyID > 0
GROUP BY so.CompanyID,
so.OrderNbr,
so.OrderType,
ic.ItemClassID,
ic.Descr
) AS X
GROUP BY CompanyID, OrderNbr, OrderType, InvoiceNbr;
GO

On my end, with a view similar to yours GI results contain only records accessible from the current company. Below are code snippets and screenshots to prove this:
SQL view:
CREATE VIEW [dbo].[View1]
AS
SELECT
CompanyID,
OrderNbr,
OrderType,
SUM(LabourHours) AS LabourHours
FROM
(
SELECT
so.CompanyID,
so.OrderNbr,
so.OrderType,
SUM(sol.OrderQty) AS LabourHours
FROM SOOrder so
LEFT JOIN SOLine sol ON so.OrderType = sol.OrderType AND so.OrderNbr = sol.OrderNbr and so.CompanyID = sol.CompanyID
LEFT JOIN InventoryItem inv ON sol.InventoryID = inv.InventoryID and sol.CompanyID = inv.CompanyID
LEFT JOIN INItemClass ic ON inv.ItemClassID = ic.ItemClassID and inv.CompanyID = ic.CompanyID
WHERE so.CompanyID > 0
GROUP BY so.CompanyID,
so.OrderNbr,
so.OrderType,
ic.ItemClassID,
ic.Descr
) AS X
GROUP BY CompanyID, OrderNbr, OrderType
GO
DAC:
using System;
using PX.Data;
namespace View
{
[Serializable]
public class View1: IBqlTable
{
#region OrderNbr
[PXDBString(15, IsKey = true, IsUnicode = true, InputMask = "")]
[PXUIField(DisplayName = "Order Nbr")]
public string OrderNbr { get; set; }
public class orderNbr : IBqlField{}
#endregion
#region OrderType
[PXDBString(2, IsKey = true, IsFixed = true, InputMask = "")]
[PXUIField(DisplayName = "Order Type")]
public string OrderType { get; set; }
public class orderType : IBqlField{}
#endregion
#region LabourHours
[PXDBDecimal()]
[PXUIField(DisplayName = "Labour Hours")]
public Decimal? LabourHours { get; set; }
public class labourHours : IBqlField{}
#endregion
}
}
GI result for Company:
GI result for Company2:
Per request below, I've added Sales Order of the SO Type and 001252 Number in both companies. Please see screenshots below with results (nothing unexpected or strange):
GI result for Company:
GI result for Company2:

Related

Adding Customer Class to GLTran \ GLTranR to see in screen GL404000 (Account Details)

I am currently trying to add the customer account class to the viewing area of the GL404000 screen with the by extending the GLTran DAC.
The AccountID, AccountCD and Account name are already available so I thought it would be an easy task.
In GLTranR, I saw where they were pulling in the account data:
public new abstract class referenceID : PX.Data.BQL.BqlInt.Field<referenceID> { }
[PXDBInt()]
[PXDimensionSelector("BIZACCT", typeof(Search<BAccountR.bAccountID>), typeof(BAccountR.acctCD), DescriptionField = typeof(BAccountR.acctName), DirtyRead = true)]
[PXUIField(DisplayName = CR.Messages.BAccountCD, Enabled = false, Visible = false)]
public override Int32? ReferenceID
{
get
{
return this._ReferenceID;
}
set
{
this._ReferenceID = value;
}
}
The line that I attempted to change to my need was the [PXDimensionSelector()] however I cannot get this to pull in the class data. Even when I dont change the code at all it will not populate the column.
public new abstract class usrBusinessAccountClass : PX.Data.BQL.BqlInt.Field<usrBusinessAccountClass> { }
protected Int32? _UsrBusinessAccountClass;
[PXDBInt()]
[PXDimensionSelector("BIZACCT", typeof(Search<BAccountR.bAccountID>), typeof(BAccountR.acctCD), DescriptionField = typeof(BAccountR.acctClass), DirtyRead = true)]
[PXUIField(DisplayName = "Business Account Class", Enabled = false, Visible = false)]
public virtual Int32? UsrBusinessAccountClass
{
get {return _UsrBusinessAccountClass;}
set{ _UsrBusinessAccountClass = value;} // set does work but value does not???
}
just for a test I changed the setter to:
set { _UsrBusinessAccountClass = 1234; }
And that populated the column with the value 1234, so that is why I think my issue is just with selecting the class.
I would show this but I need 10 rep to post images.
You are on the proper track. The following code shows how to retrieve additional data to display within the screen.
Non-Database backed field on the DAC you wish to display data on :
public sealed class GLTranRExtension : PXCacheExtension<GLTranR>
{
public abstract class usrClassID : BqlString.Field<usrClassID>
{
}
[PXString(10, IsUnicode = true, InputMask = ">aaaaaaaaaa")]
[PXSelector(typeof(CRCustomerClass.cRCustomerClassID), DescriptionField = typeof(CRCustomerClass.description))]
[PXUIField(DisplayName = "Business Account Class")]
public string UsrClassID { get; set; }
}
Graph extension in which the extension field is then populated with data :
public class AccountByPeriodEnqExtension : PXGraphExtension<AccountByPeriodEnq>
{
protected virtual void __(Events.RowSelecting<GLTranR> e)
{
if(e.Row is GLTranR row)
{
GLTranRExtension rowExt = row.GetExtension<GLTranRExtension>();
using(new PXConnectionScope())
{
BAccount bAccount = PXSelectReadonly<BAccount, Where<BAccount.bAccountID, Equal<Required<BAccount.bAccountID>>>>.Select(this.Base, row.ReferenceID);
if(bAccount != null)
{
rowExt.UsrClassID = bAccount.ClassID;
}
}
}
}
}
You will also need to add within the GL404000 the UI elements for your new extension fields. The result will look as follows :

Unable to Update Custom Field in Sales Quote Screen From Sales Order on an Action Event

I have created an Action in Sales Quotes screen to create a sales order. The sales order is getting created. I want the created Order Nbr to be populated in a custom field of Sales Quote Screen and the Action button to be disabled if the Sales order is created. Though I am not getting any error in the system.
When I refresh the Sales Quote Screen I get the exact result, but not during the Click of Create SO Action.
I am not sure where I am going wrong. Please refer the code and Image below: Thanks.
Following is my Code :
public class QuoteMaint_Extension : PXGraphExtension<QuoteMaint>
{
#region Event Handlers
protected void CRQuote_RowSelected(PXCache cache, PXRowSelectedEventArgs e)
{
var row = (CRQuote)e.Row;
CRQuoteExt quoteExt = PXCache<CRQuote>.GetExtension<CRQuoteExt>(row);
if (quoteExt.UsrOrderNbr != null)
{
createSalesOrder.SetEnabled(false);
}
else
{
createSalesOrder.SetEnabled(true);
}
}
#endregion
#region Create Sales Order
public PXAction<CRQuote> createSalesOrder;
[PXUIField(DisplayName = "Create SO", MapEnableRights = PXCacheRights.Update, MapViewRights = PXCacheRights.Update)]
[PXProcessButton(CommitChanges = true)]
public IEnumerable CreateSalesOrder(PXAdapter adapter)
{
QuoteMaint graphObject = PXGraph.CreateInstance<QuoteMaint>();
foreach (CRQuote quote in adapter.Get())
{
//Create resultset for Quote Details
PXResultset<CROpportunityProducts> PXSetLine = PXSelect<CROpportunityProducts,
Where<CROpportunityProducts.quoteID,
Equal<Required<CROpportunityProducts.quoteID>>>>.Select(this.Base, quote.QuoteID);
List<CROpportunityProducts> QuoteList = new List<CROpportunityProducts>();
foreach (CROpportunityProducts line in PXSetLine)
{
QuoteList.Add(line);
}
PXLongOperation.StartOperation(this, delegate ()
{
CreateSalesOrderMethod(quote, QuoteList);
});
yield return quote;
}
}
//Private Method for Create Sales Order
public virtual void CreateSalesOrderMethod(CRQuote quote, List<CROpportunityProducts> QuoteList)
{
//Base.Save.Press();
bool var_orderCreated = false;
bool erroroccured = false;
string ErrMsg = "";
SOOrderEntry orderGraphObjet = PXGraph.CreateInstance<SOOrderEntry>();
SOOrder orderHeaderObject = new SOOrder();
QuoteMaint currGRPH = PXGraph.CreateInstance<QuoteMaint>();
var Extension = this.Base.GetExtension<QuoteMaint_Extension>();
try
{
BAccount customer = PXSelect<BAccount, Where<BAccount.bAccountID, Equal<Current<CRQuote.bAccountID>>>>.Select(this.Base, quote.BAccountID);
if (customer.Type == "CU")
{
orderHeaderObject.CustomerID = quote.BAccountID;
}
else
{
throw new PXException("Business Account not converted to Customer yet");
}
orderHeaderObject.CuryOrderTotal = quote.CuryProductsAmount;
orderHeaderObject.CuryTaxTotal = quote.CuryTaxTotal;
orderHeaderObject.OrderDesc = quote.Subject;
orderHeaderObject = orderGraphObjet.CurrentDocument.Insert(orderHeaderObject);
orderGraphObjet.CurrentDocument.Current = orderHeaderObject;
orderGraphObjet.Actions.PressSave();
orderHeaderObject = orderGraphObjet.CurrentDocument.Current;
foreach (CROpportunityProducts tran in QuoteList)
{
CROpportunityProductsExt xOppProductExt = PXCache<CROpportunityProducts>.GetExtension<CROpportunityProductsExt>(tran);
SOLine transline = new SOLine();
SOLineExt _soLext = PXCache<SOLine>.GetExtension<SOLineExt>(transline);
transline.OrderNbr = orderHeaderObject.OrderNbr;
transline.BranchID = orderHeaderObject.BranchID;
transline.InventoryID = tran.InventoryID;
transline.TranDesc = tran.Descr;
transline.UOM = tran.UOM;
transline.OrderQty = tran.Quantity;
transline.SiteID = tran.SiteID;
transline.CuryUnitPrice = tran.CuryUnitPrice;
transline.CuryExtPrice = tran.CuryExtPrice;
_soLext.UsrXSeqID = xOppProductExt.UsrXSequenceID;
_soLext.UsrXGroupID = xOppProductExt.UsrXGroupID;
_soLext.UsrInternalRemk = xOppProductExt.UsrInternalRemk;
orderGraphObjet.Transactions.Insert(transline);
}
orderGraphObjet.Actions.PressSave();
var_orderCreated = true;
}
catch (Exception e)
{
erroroccured = true;
ErrMsg = e.Message;
}
if (erroroccured)
{
throw new PXException("Cannot create Order: " + ErrMsg);
}
else
{
if(var_orderCreated)
{
CRQuote QUOT = Base.Quote.Current;
CRQuoteExt QUOT_EXT = PXCache<CRQuote>.GetExtension<CRQuoteExt>(QUOT);
QUOT_EXT.UsrOrderNbr = orderHeaderObject.OrderNbr;
Base.Quote.Update(QUOT);
Base.Save.Press();
}
}
}
#endregion
}
}
DAC FIELD :
#region UsrOrderNbr
[PXDBString(50)]
[PXUIField(DisplayName = "Sales Order Nbr", IsReadOnly = true)]
[PXSelector(
typeof(Search<SOOrder.orderNbr>),
typeof(SOOrder.orderType),
typeof(SOOrder.orderNbr),
typeof(SOOrder.curyOrderTotal),
typeof(SOOrder.status),
Filterable = true)]
public virtual string UsrOrderNbr { get; set; }
public abstract class usrOrderNbr : PX.Data.BQL.BqlString.Field<usrOrderNbr> { }
#endregion
The DAC extension is fetched from transLine object before the SOLine keys are defined. Try moving the GetExtension call after transLine is inserted in the dataview.
SOLine transline = new SOLine();
SOLineExt _soLext = PXCache<SOLine>.GetExtension<SOLineExt>(transline);
The pattern should look like this:
Create empty DAC object
Insert DAC object in dataview
Get DAC extension and assign custom field
Update DAC object in dataview

Need help in selector control

I created a selector control which displays a list of all serial #s from INItemLotSerial table, it works fine, the problem is the description field is showing InventoryID, how to show InventoryCD. Please have a look at below sample code.
[PXSelector(typeof(Search<INItemLotSerial.lotSerialNbr>),
new Type[] { typeof(INItemLotSerial.lotSerialNbr), typeof(INItemLotSerial.inventoryID) },
SubstituteKey = typeof(INItemLotSerial.lotSerialNbr), DescriptionField = typeof(INItemLotSerial.inventoryID))]
// i also joined with InventoryItem but this doesn't works.
[PXSelector(typeof(Search2<INItemLotSerial.lotSerialNbr,
LeftJoinSingleTable<InventoryItem, On<InventoryItem.inventoryID,Equal<INItemLotSerial.inventoryID>>>>),
new Type[] { typeof(INItemLotSerial.lotSerialNbr), typeof(INItemLotSerial.inventoryID) },
SubstituteKey = typeof(INItemLotSerial.lotSerialNbr), DescriptionField = typeof(InventoryItem.inventoryCD))]
The main problem with DescriptionField property is that it is waiting for getting the field from the same table for which Selector is written. But in the case of ID/CD usually, the CD is not present in the table where ID is present, except the main table.
UPDATED I have removed previous code (implementation using custom attributes and FieldSelecting event handler) because of the performance issues which it is bringing with it. The code below is resulting with the same lookup but getting the data with one inner join instead of all the requests which the previous code was doing.
You can do the following to get this lookup with description:
Create a PXProjection on INItemLotSerial and InventoryItem tables like below:
[PXCacheName("Lot Serials with Inventory CD")]
[PXProjection(typeof(Select2<INItemLotSerial,
InnerJoin<InventoryItem,
On<INItemLotSerial.inventoryID, Equal<InventoryItem.inventoryID>>>>))]
public class INItemLotSerialWithInventoryItem : IBqlTable
{
[PXDBInt(BqlField = typeof(INItemLotSerial.inventoryID))]
[PXUIField(DisplayName = "Inventory ID", Visibility = PXUIVisibility.Visible, Visible = false)]
public virtual int? InventoryID { get; set; }
public abstract class inventoryID : IBqlField { }
[PXDBString(InputMask = "", IsUnicode = true, BqlField = typeof(InventoryItem.inventoryCD))]
[PXUIField(DisplayName = "Inventory ID")]
public virtual string InventoryCD { get; set; }
public abstract class inventoryCD : IBqlField { }
[PXDBString(InputMask = "", IsUnicode = true, BqlField = typeof(INItemLotSerial.lotSerialNbr))]
[PXUIField(DisplayName = "Lot/Serial Nbr")]
public virtual string LotSerialNbr { get; set; }
public abstract class lotSerialNbr : IBqlField { }
}
Set your selector to use this PXProjection like below:
[PXSelector(typeof(Search<INItemLotSerialWithInventoryItem.lotSerialNbr>),
new Type[] { typeof(INItemLotSerialWithInventoryItem.lotSerialNbr) },
SubstituteKey = typeof(INItemLotSerialWithInventoryItem.lotSerialNbr),
DescriptionField = typeof(INItemLotSerialWithInventoryItem.inventoryCD))]
As a result, you will get lookup like below:

BQL Join with a custom table giving Incorrect Syntax near '[keyword]' error at run time

I'm trying to create a custom screen for scheduling the deliveries of the shipments in Acumatica. I created a custom table and DAC called DeliverySchedule for this purpose. And I create a data view that joins SOShipLine table with this new custom table. But when I load the screen I get a runtime error saying Incorrect Syntax near '='.
Error does not occur when I just join two Acumatica tables (SOShipment and SOShipLine). It happens when I join my custom table into the mix. I tried using the Request Profiler screen in Acumatica to debug but I do not have much information from that (or probably I do not know how to use it and read the data it provides)
public PXSelectJoin<SOShipLine, InnerJoin<SOShipment, On<SOShipment.shipmentNbr, Equal<SOShipLine.shipmentNbr>>, LeftJoin<DeliverySchedule, On<DeliverySchedule.shipmentNbr, Equal<SOShipLine.shipmentNbr>, And<DeliverySchedule.lineNbr, Equal<SOShipLine.lineNbr>>>>>, Where<SOShipment.status, Equal<SOShipmentStatus.open>>> Shipments;
DAC
[Serializable]
public class DeliverySchedule : IBqlTable
{
#region ShipmentNbr
        [PXString(15, IsKey = true)]
[PXDBDefault(typeof(SOShipLine.shipmentNbr))]
[PXParent(typeof(Select<SOShipLine, Where<SOShipLine.shipmentNbr, Equal<Current<DeliverySchedule.shipmentNbr>>, And<SOShipLine.lineNbr, Equal<Current<DeliverySchedule.lineNbr>>>>>))]
[PXUIField(DisplayName = "Shipment No.")]
public string ShipmentNbr { get; set; }
public class shipmentNbr : IBqlField { }
        #endregion
#region LineNbr
[PXDBInt(IsKey = true)]
[PXDBDefault(typeof(SOShipLine.lineNbr))]
[PXParent(typeof(Select<SOShipLine, Where<SOShipLine.shipmentNbr, Equal<Current<DeliverySchedule.shipmentNbr>>, And<SOShipLine.lineNbr, Equal<Current<DeliverySchedule.lineNbr>>>>>))]
[PXUIField(DisplayName = "Line Nbr.", Visible = false)]
public Int32? LineNbr { get; set; }
public class lineNbr : IBqlField { }
#endregion
#region InventoryID
[PXDBInt]
[PXUIField(DisplayName = "Inventory ID")]
public Int32? InventoryID { get; set; }
public class inventoryID : IBqlField { }
#endregion
#region TransportID
[PXDBInt]
[PXUIField(DisplayName = "Transport")]
public Int32? TransportID { get; set; }
public class transportID : IBqlField { }
#endregion
#region DriverID
[PXDBInt]
[PXUIField(DisplayName = "Driver/ Captain")]
public Int32? DriverID { get; set; }
public class driverID : IBqlField { }
#endregion
#region TripNbr
[PXDBString(15)]
[PXUIField(DisplayName = "Trip No.")]
public string TripNbr { get; set; }
public class tripNbr : IBqlField { }
#endregion
#region ScheduledDelivery
[PXDBDateAndTime(DisplayNameDate = "Scheduled Delivery Date", DisplayNameTime = "Scheduled Delivery Time")]
public DateTime? ScheduledDelivery { get; set; }
public class scheduledDelivery : IBqlField { }
#endregion
#region CustInvLvlBeforeDel
[PXDBDecimal]
[PXUIField(DisplayName = "Cust. Inv. Lvl. (Before Delivery)")]
public decimal? CustInvLvlBeforeDel { get; set; }
public class custInvLvlBeforeDel : IBqlField { }
#endregion
#region CustInvLvlAfterDel
[PXDBDecimal]
[PXUIField(DisplayName = "Cust. Inv. Lvl. (After Delivery)")]
public decimal? CustInvLvlAfterDel { get; set; }
public class custInvLvlAfterDel : IBqlField { }
#endregion
}
Trace Logs
Info. from the Tables column shown in the screen shot pasted below as text.
Tables
##DBTS, IDENT_CURRENT('WatchDog') OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */
##DBTS, IDENT_CURRENT('WatchDog') OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */
Favorite
##DBTS, IDENT_CURRENT('WatchDog') OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */
##DBTS, IDENT_CURRENT('WatchDog') OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */
"[WikiPage].[PageID], [WikiPage].[WikiID], [WikiPage].[ArticleType], [WikiPage].[ParentUID], [WikiPage].[Number], [WikiPage].[Name], [WikiPage].[Versioned], [WikiPage].[Folder], [WikiPage].[NoteID], NULL, NULL, NULL, [WikiPage].[CreatedByID], [WikiPage].[CreatedDateTime], [WikiPage].[LastModifiedByID], [WikiPage].[LastModifiedDateTime], [WikiPage].[tstamp], [WikiPage].[StatusID], [WikiPage].[ApprovalGroupID], [WikiPage].[ApprovalUserID], [WikiPage].[Width], [WikiPage].[Height], [WikiPage].[IsHtml]
FROM [WikiPage] [WikiPage]
WHERE [WikiPage].CompanyID IN (1, 2) AND 8 = SUBSTRING([WikiPage].CompanyMask, 1, 1) & 8 AND [WikiPage].[Name] = #P0
ORDER BY [WikiPage].[PageID] OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */"
##DBTS, IDENT_CURRENT('WatchDog') OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */
##DBTS, IDENT_CURRENT('WatchDog') OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */
WatchDog
SMPerformanceSettings
##DBTS, IDENT_CURRENT('WatchDog') OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */
"TOP (201) [SOShipLine].[ShipmentNbr], [SOShipLine].[ShipmentType], [SOShipLine].[LineNbr], [SOShipLine].[SortOrder], [SOShipLine].[CustomerID], [SOShipLine].[ShipDate], [SOShipLine].[Confirmed], [SOShipLine].[Released], [SOShipLine].[LineType], [SOShipLine].[OrigOrderType], [SOShipLine].[OrigOrderNbr], [SOShipLine].[OrigLineNbr], [SOShipLine].[OrigSplitLineNbr], [SOShipLine].[Operation], [SOShipLine].[OrigPlanType], [SOShipLine].[InvtMult], [SOShipLine].[InventoryID], [SOShipLine].[PlanType], [SOShipLine].[SubItemID], [SOShipLine].[SiteID], [SOShipLine].[LocationID], [SOShipLine].[LotSerialNbr], [SOShipLine].[ExpireDate], [SOShipLine].[OrderUOM], [SOShipLine].[UOM], [SOShipLine].[ShippedQty], [SOShipLine].[BaseShippedQty], [SOShipLine].[BaseOriginalShippedQty], [SOShipLine].[UnassignedQty], [SOShipLine].[CompleteQtyMin], [SOShipLine].[BaseOrigOrderQty], [SOShipLine].[OrigOrderQty], [SOShipLine].[UnitCost], [SOShipLine].[ExtCost], [SOShipLine].[UnitPrice], [SOShipLine].[DiscPct], [SOShipLine].[AlternateID], [SOShipLine].[TranDesc], [SOShipLine].[UnitWeigth], [SOShipLine].[UnitVolume], [SOShipLine].[ExtWeight], [SOShipLine].[ExtVolume], [SOShipLine].[ProjectID], [SOShipLine].[TaskID], [SOShipLine].[ReasonCode], [SOShipLine].[IsFree], [SOShipLine].[ManualPrice], [SOShipLine].[ManualDisc], [SOShipLine].[IsUnassigned], [SOShipLine].[DiscountID], [SOShipLine].[DiscountSequenceID], [SOShipLine].[DetDiscIDC1], [SOShipLine].[DetDiscSeqIDC1], [SOShipLine].[DetDiscIDC2], [SOShipLine].[DetDiscSeqIDC2], [SOShipLine].[DetDiscApp], [SOShipLine].[DocDiscIDC1], [SOShipLine].[DocDiscSeqIDC1], [SOShipLine].[DocDiscIDC2], [SOShipLine].[DocDiscSeqIDC2], [SOShipLine].[ShipComplete], [SOShipLine].[RequireINUpdate], [SOShipLine].[NoteID], (SELECT TOP (1) [Note_s65].[NoteText] FROM [dbo].[Note] [Note_s65] WHERE [Note_s65].CompanyID IN (1, 2) AND 8 = SUBSTRING([Note_s65].CompanyMask, 1, 1) & 8 AND [Note_s65].[NoteId] = [SOShipLine].[NoteID]), (SELECT TOP (1) COUNT(*) FROM [dbo].[NoteDoc] [NoteDoc_s67] WHERE [NoteDoc_s67].CompanyID IN (1, 2) AND 8 = SUBSTRING([NoteDoc_s67].CompanyMask, 1, 1) & 8 AND [NoteDoc_s67].[NoteId] = [SOShipLine].[NoteID]), NULL, [SOShipLine].[CreatedByID], [SOShipLine].[CreatedByScreenID], [SOShipLine].[CreatedDateTime], [SOShipLine].[LastModifiedByID], [SOShipLine].[LastModifiedByScreenID], [SOShipLine].[LastModifiedDateTime], [SOShipLine].[tstamp], [SOShipLine].[UsrAPIGravity], [SOShipLine].[UsrMeterID], [SOShipLine].[UsrGrossQty], [SOShipLine].[UsrTemperature], [SOShipLine].[UsrToLocationID], [SOShipLine].[UsrBOLQty], [SOShipLine].[UsrBeginningTotalizer], [SOShipLine].[UsrEndingTotalizer], [SOShipment].[ShipmentNbr], [SOShipment].[ShipDate], [SOShipment].[Operation], [SOShipment].[ShipmentType], [SOShipment].[CustomerID], [SOShipment].[CustomerLocationID], [SOShipment].[SiteID], [SOShipment].[DestinationSiteID], [SOShipment].[ShipAddressID], [SOShipment].[ShipContactID], [SOShipment].[FOBPoint], [SOShipment].[ShipVia], [SOShipment].[UseCustomerAccount], [SOShipment].[Resedential], [SOShipment].[SaturdayDelivery], [SOShipment].[Insurance], [SOShipment].[GroundCollect], [SOShipment].[LabelsPrinted], [SOShipment].[PickListPrinted], [SOShipment].[ShippedViaCarrier], [SOShipment].[ShipTermsID], [SOShipment].[ShipZoneID], [SOShipment].[LineTotal], [SOShipment].[CuryID], [SOShipment].[CuryInfoID], [SOShipment].[CuryFreightCost], [SOShipment].[FreightCost], [SOShipment].[CuryFreightAmt], [SOShipment].[FreightAmt], [SOShipment].[CuryPremiumFreightAmt], [SOShipment].[PremiumFreightAmt], [SOShipment].[CuryTotalFreightAmt], [SOShipment].[TotalFreightAmt], [SOShipment].[TaxCategoryID], [SOShipment].[NoteID], NULL, NULL, NULL, [SOShipment].[Hold], [SOShipment].[Confirmed], [SOShipment].[Released], [SOShipment].[Status], [SOShipment].[LineCntr], [SOShipment].[BilledOrderCntr], [SOShipment].[UnbilledOrderCntr], [SOShipment].[ReleasedOrderCntr], [SOShipment].[ControlQty], [SOShipment].[ShipmentQty], [SOShipment].[ShipmentWeight], [SOShipment].[ShipmentVolume], [SOShipment].[PackageLineCntr], [SOShipment].[PackageWeight], [SOShipment].[IsPackageValid], [SOShipment].[CreatedByID], [SOShipment].[CreatedByScreenID], [SOShipment].[CreatedDateTime], [SOShipment].[LastModifiedByID], [SOShipment].[LastModifiedByScreenID], [SOShipment].[LastModifiedDateTime], [SOShipment].[tstamp], [SOShipment].[WorkgroupID], [SOShipment].[OwnerID], [SOShipment].[FreeItemQtyTot], CASE WHEN ( [SOShipment].[Status] IS NULL) THEN 'A' ELSE [SOShipment].[Status] END, [SOShipment].[UsrBOLNbr], [DeliverySchedule].[LineNbr], [DeliverySchedule].[InventoryID], [DeliverySchedule].[TransportID], [DeliverySchedule].[DriverID], [DeliverySchedule].[TripNbr], [DeliverySchedule].[CustInvLvlBeforeDel], [DeliverySchedule].[CustInvLvlAfterDel]
FROM [SOShipLine] [SOShipLine]
INNER JOIN [SOShipment] [SOShipment] ON [SOShipment].CompanyID = 2 AND [SOShipment].[ShipmentNbr] = [SOShipLine].[ShipmentNbr]
LEFT JOIN [DeliverySchedule] [DeliverySchedule] ON [DeliverySchedule].CompanyID = 2 AND = [SOShipLine].[ShipmentNbr] AND [DeliverySchedule].[LineNbr] = [SOShipLine].[LineNbr]
WHERE [SOShipLine].CompanyID = 2 AND [SOShipment].[Status] = 'N'
ORDER BY [SOShipLine].[ShipmentNbr], [SOShipLine].[ShipmentType], [SOShipLine].[LineNbr] OPTION(OPTIMIZE FOR UNKNOWN) /* PA.20.81.00 */"
It looks like your ShipmentNbr field should use a DB type such as PXDBString vs PXString. Change your attribute on your key field to see if this helps (to [PXDBString(15, IsKey = true)]). If you are trying to join it to other tables it is most likely failing in the join statements because its an unbound field as you have it posted in your question. Useage of an unbound field in a Join or Where clause might leave the other side of the = statement empty in the query generated for SQL.
Example:
#region ShipmentNbr
[PXDBString(15, IsKey = true)]
[PXDBDefault(typeof(SOShipLine.shipmentNbr))]
[PXParent(typeof(Select<SOShipLine, Where<SOShipLine.shipmentNbr, Equal<Current<DeliverySchedule.shipmentNbr>>, And<SOShipLine.lineNbr, Equal<Current<DeliverySchedule.lineNbr>>>>>))]
[PXUIField(DisplayName = "Shipment No.")]
public string ShipmentNbr { get; set; }
public class shipmentNbr : IBqlField { }
#endregion
Also you only need one PXParent to a table (you can have multiple PXParent - but different tables). You can use any field to place the PXParent attribute but should only need it once for a given table. (you have a PXParent to SOShipLine on ShipmentNbr and LineNbr)

Acumatica - Possible to create several numberingId with existing numberingId

i have some problems with AutoNumberAttribute in Acumatica. In my Project Issue screen i can create new entity with existing numberingId (see screenshot below)
Field selector with AutoNumberAttribute
But other entities like POOrder, Case haven't this promlems. Code for this shown below:
[Serializable]
[PXEMailSource]
[PXPrimaryGraph(typeof(ProjectIssueMaint))]
[PXCacheName(Messages.ProjectIssue.CacheName)]
public class ProjectIssue : BaseCache, IBqlTable, IAssign, IPXSelectable
{
[PXDBIdentity]
[PXUIField(Visible = false, Visibility = PXUIVisibility.Invisible, DisplayName = Messages.ProjectIssue.NumberId)]
public virtual int? ProjectIssueId
{
get;
set;
}
[PXDefault]
[PXFieldDescription]
[PXDBString(10, IsKey = true, IsUnicode = true, InputMask = ">CCCCCCCCCCCCCCC")]
[PXUIField(DisplayName = Messages.ProjectIssue.NumberId, Required = true)]
[PXSelector(typeof(Search<projectIssueCd>),
typeof(projectIssueCd),
typeof(projectId),
typeof(projectTaskId),
typeof(classId),
typeof(summary),
typeof(status),
typeof(ownerID),
Filterable = true)]
[AutoNumber(typeof(ProjectManagementSetup.projectIssueNumberingId), typeof(createdDateTime))]
public virtual string ProjectIssueCd
{
get;
set;
}
public abstract class projectIssueCd : IBqlField
{
}
public abstract class projectIssueId : IBqlField
{
}
}
[Serializable]
[PXCacheName(Messages.ProjectManagementSetup.CacheName)]
public class ProjectManagementSetup : BaseCache, IBqlTable
{
[PXDBString(10, IsUnicode = true, InputMask = ">aaaaaaaaaa")]
[PXDefault(Constants.ProjectIssue.NumberingId)]
[PXSelector(typeof(Numbering.numberingID), DescriptionField = typeof(Numbering.descr))]
[PXUIField(DisplayName = Messages.ProjectManagementSetup.ProjectIssueNumberingSequence)]
public virtual string ProjectIssueNumberingId
{
get;
set;
}
public abstract class projectIssueNumberingId : IBqlField
{
}
}
public class ProjectIssueMaint : PXGraph<ProjectIssueMaint, ProjectIssue>
{
[PXViewName(Messages.ProjectIssue.CacheName)]
[PXCopyPasteHiddenFields(typeof(ProjectIssue.status))]
public PXSelect<ProjectIssue> ProjectIssue;
[PXHidden]
[PXCheckCurrent]
public PXSetup<ProjectManagementSetup> ProjectManagementSetup;}
public class ProjectManagementSetupMaint : PXGraph<ProjectManagementSetupMaint>
{
public PXSave<ProjectManagementSetup> Save;
public PXCancel<ProjectManagementSetup> Cancel;
public PXSelect<ProjectManagementSetup> ProjectManagementSetup;
}
I reproproduce this issue by change the last number field in the numbering sequence screen (see screenshot https://snag.gy/UpIe8a.jpg).
So somebody know why this maybe happend? Any information will help me)
The AutoNumberAttribute completely relies on the configuration of the associated Numbering Sequence and does not have built-in validation to prevent insertion of the record with the duplicated number, which was generated by the AutoNumberAttribute. Since your table is built with A Pair of Columns with Key Substitution in the UI, you must add a unique index consisting of the CompanyID and ProjectIssueCd columns to prevent the insertion of multiple ProjectIssue records with the same ProjectIssueCd on the database level.
CREATE UNIQUE NONCLUSTERED INDEX [ProjectIssue_ProjectIssueCd_Uindex] ON [dbo].[ProjectIssue]
(
[CompanyID] ASC,
[ProjectIssueCd] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, SORT_IN_TEMPDB = OFF, IGNORE_DUP_KEY = OFF, DROP_EXISTING = OFF, ONLINE = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)

Resources