Hey, @amajors-
I actually just got done with a proof of concept for this exact issue. I ended up creating a customization to handle it. I created a rowpersisting event on the corresponding RegisterEntry that gets generated. It finds the account group associated to the stock/non-stock item and reassigns it on the corresponding project transaction. Code below that extends RegisterEntry graph. Again, proof of concept, we are in the sales solution cycle on this. I also have an open case with Acumatica on this to see if there are workarounds in the system without having to do a customization. Will post here if I make heads or tails of it.
//Details Event Handler
protected void PMTran_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
{
var row = (PMTran)e.Row;
InventoryItem item = PXSelect<InventoryItem, Where<InventoryItem.inventoryID, Equal<Required<InventoryItem.inventoryID>>>>.Select(Base, row.InventoryID);
if (item != null)
{
PMAccountGroup account = PXSelect<PMAccountGroup, Where<PMAccountGroup.accountID, Equal<Required<PMAccountGroup.accountID>>>>.Select(Base, item.COGSAcctID);
if (account != null)
{
row.AccountGroupID = account.GroupID;
cache.Update(row);
}
}
}
@rhooper91 have you tried an import scenario to update the Project Transaction before release? I’m not knowledgeable enough to create one that works but I would think that you could update the Group based on the inventory item account.
@amajors,
I have not tried with import scenario but I imagine it would totally be possible. You would create the generic inquiry to search for new project transactions and include the current and join the future account group from the item in that table. I would imagine you could drop lines from the table where the current == future account group to prevent it from getting too large.
You could then write a business event to trigger when a new record is added to that table that triggers the import scenario to “correct” the project transaction.
That is essentially what my code is doing, it’s just doing it in real time. The problem I have with import scenarios is that there will always be a gap in time between when the transaction is created and when the import scenario triggers and in that you can find yourself with some transactions that never got corrected before they were released. So if you go the import scenario route it should be supported with a good process to ensure releasing unadjusted transactions won’t happen.
Hey, @amajors-
I actually just got done with a proof of concept for this exact issue. I ended up creating a customization to handle it. I created a rowpersisting event on the corresponding RegisterEntry that gets generated. It finds the account group associated to the stock/non-stock item and reassigns it on the corresponding project transaction. Code below that extends RegisterEntry graph. Again, proof of concept, we are in the sales solution cycle on this. I also have an open case with Acumatica on this to see if there are workarounds in the system without having to do a customization. Will post here if I make heads or tails of it.
//Details Event Handler
protected void PMTran_RowPersisting(PXCache cache, PXRowPersistingEventArgs e)
{
var row = (PMTran)e.Row;
InventoryItem item = PXSelect<InventoryItem, Where<InventoryItem.inventoryID, Equal<Required<InventoryItem.inventoryID>>>>.Select(Base, row.InventoryID);
if (item != null)
{
PMAccountGroup account = PXSelect<PMAccountGroup, Where<PMAccountGroup.accountID, Equal<Required<PMAccountGroup.accountID>>>>.Select(Base, item.COGSAcctID);
if (account != null)
{
row.AccountGroupID = account.GroupID;
cache.Update(row);
}
}
}
How are you dealing with the duplication of quantities. From my tests the Project Type Appointment creates a PM transaction and then the inventory transaction duplicates the parts on the project.
@amajors,
In my scenario I was just proving out that it could be done. I would imagine that if an inventory transaction was also released on an inventory item and the account group is not aligned, the same process would need to occur to correct the additional entry that gets generated on appointment completion. So you would be updating both.
Again.. not ideal. The ideal would be for the system to allow for defaulting based on the item but until that’s instituted, this appears to be the next best thing- whether through customization or import scenario.
Also, to confirm I’m reading you correctly, are you stating that the item gets double counted if project inventory is turned on? Or are you asking how to correct the inventory entry that gets created? My response above corresponds to the latter.
Hi @amajors - were you able to find a solution? Thank you!
Hi @amajors - were you able to find a solution? Thank you!
Not at this time. Without a change to the system via update or customization, I don’t see this working which is extremely disappointing since we invested in it and it doesn’t do what we expected.
@amajors Hi! Here is an article that was prepared by a business analyst from Acumatica some time ago that may help you. It describes a recommended configuration to work with Field Services and billing to project transactions.
Like you mention in your comment, it’s only possible to set one account group per service order type, and users may want to use different account groups for different types of item for example.
Recommended Settings
The sample scenario is prepared on the basis of SalesDemo dataset.
- Configure an account group that will be used for collecting PM transactions originating from appointments. You will further reallocate these transactions to WIP account group configured below.
- Account Group ID = UNBILLED (it is already preconfigured in SalesDemo)
- Type = Asset
- Account tab: you can either map an account or not map it to an account group - we are not using this account anywhere in the process flow (thus, Account tab can be empty) (this will not change the behaviour of a PM transaction generated from an appointment: this PM transaction will not have GL accounts and will not be posted to GL)
- If you would like the expense related to issuing stock items from a warehouse to be recorded to project, map the expense account specified in the issue reason code to a project account group as follows:
- Account Group ID = MATEXP
- Type = Expense
- Accounts tab: map the expense account that will be used in the issue reason code - 50000 COGS - Inventory in this example
- An account group for storing records that will be billed on a project time&material basis
- Account Group ID = TOINVOICE
- Type = Off-Balance
- Accounts tab: empty
-
- An account group for recording non-stock and service related project expense
- Account Group ID = LABOR (it is already preconfigured in SalesDemo)
- Type = Expense
- Accounts tab: we are not using these account anywhere in the process flow described below (thus, Account tab can be empty)
- An account group for recording project income originating from project billing
- Account Group ID = REVENUE (it is already preconfigured in SalesDemo)
- Type = Income
- Accounts tab: at least 1 account must be mapped to this account group for the project invoice to be generated. 40000 Income account used in this example
- If you would like the expense related to issuing stock items from a warehouse to be recorded to project, configure the following reason code
- Reason Code = PROJECT (it is already preconfigured in SalesDemo, but has Sales Account mapped to project and a Sales Subaccount, which need to be cleared to avoid unnecessary transactions generated for project)
- Account = 50000 COGS - Inventory.
- This account is now mapped to a MATEXP project account group, which means that release of issue line with a project key and PROJECT reason code in it will produce an inventory GL transaction, which in its turn generates a corresponding PM transaction. Thus, you will have the expense related to issuing stock items from a warehouse recorded to a project under the account group MATEXP.
- Sales Account = empty
- Sales Subaccount = empty
- On the Service Order Types (FS202300) form create a service order type with the following Billing Settings
- Service Order Type = PBC (it is already preconfigured in SalesDemo)
- Generated Billing Documents = Project Transactions
- Account Group = UNBILLED
- Reason Code = PROJECT
-
Billing Type = Cost as Cost (so that the generated PM transaction has the cost of an appointment line with no markup on top of it)
You can also use Billing Type = Revenue as Cost - it does not affect the process flow proposed
- Other settings are not described in this document as they do not affect the process of billing appointments via projects
Please be aware this allocation rule can be successfully imported only if the above described account groups are configured in the system
You can import the below described allocation rule from XML: AllocationRule-CLEARUNBILLED.xml
- Allocation Rule = CLEARUNBILLED
- Step 10 Clear UNBILLED - this step reverses what has been recorded to UNBILLED account group from the appointment
- Calculation Rules:
- Create Allocation Transaction = True
- Account Group From = UNBILLED
- Quantity Formula =NPMTran.Qty] * (-1)
- Billable Qty. Formula =1PMTran.BillableQty] * (-1)
- Amount Formula =ePMTran.ProjectCuryAmount] * (-1)
- Description Formula ='Clearing UNBILLED'
- Allocation Settings
- Post Transaction to GL = False
- Reverse Allocation = Never
- Can Be Used as a Source in Another Allocation = False
- Credit Transaction Account Group = None
- Step 20 UNBILLED to WIP - this step will produce WIP project transactions that will be taken by the billing rule configured below; these WIP transactions will be then reversed by the allocation mechanism automatically
- Calculation Rules:
- Create Allocation Transaction = True
- Select Transactions = From Previous Allocation Steps
- Range Start = 10
- Quantity Formula =RPMTran.Qty] * (-1)
- Billable Qty. Formula =QPMTran.BillableQty] * (-1)
- Amount Formula =nPMTran.ProjectCuryAmount] * (-1)
- Description Formula ='Moving UNBILLED to WIP for billing'
- Allocation Settings
- Post Transaction to GL = False
- Reverse Allocation = On AR Invoice Generation (you can use On AR Invoice Release instead if preferable)
- Can Be Used as a Source in Another Allocation = False
- Debit Transaction Account Group = Replace -> WIP (you can use another desired account group for billing, but you will have to reconfigure the billing rule accordingly)
- Credit Transaction Account Group = None
- Step 30 Non-Stock WIP to LABOR - this step will reallocate the WIP transactions related to non-stock items and services to LABOR expense account group to reflect the fact of those expenses in the project cost budget (together with the already existing stock item related one - on MATEXPENSE account group)
-
You can use any other desired expense account group.
The formulae below use the xInventoryItem.StkItem] attribute of the inventory item to distinguish between stock and non-stock item. Thanks to that stock items will be ignored and not included in this expense transaction.
Besides, you can also use the following attribute values: BInventoryItem.ItemType] to distinguish between different types of non-stock items ('S' - Service, 'E' - Expense, 'L' - Labor, 'C' - Charge, 'N' - Non-Stock Item) and reallocate them to different expense account groups if desired.
In this example we also have Post Transaction to GL = False - here the one-sided configuration is just for easing the description of the example. However, you can post this expense to GL if it is necessary and specify the necessary credit part of the transaction.
- Calculation Rules tab
- Create Allocation Transaction = True
- Select Transactions = From Previous Allocation Steps
- Range Start = 20
- Quantity Formula =IIf( InventoryItem.StkItem], 0, >PMTran.Qty])
- Billable Qty. Formula =IIf(]InventoryItem.StkItem], 0,
- Amount Formula =IIf(eInventoryItem.StkItem], 0, )PMTran.ProjectCuryAmount])
- Description Formula ='Moving non-stock WIP to LABOR expense'
- Allocation Settings tab
- Post Transaction to GL = False
- Reverse Allocation = Never
- Can Be Used as a Source in Another Allocation = False
- Debit Transaction Account Group = Replace -> LABOR (you can use another desired account group for recording the non-stock / service project expense)
- Credit Transaction Account Group = None
You can import the below described billing rule from XML: BillingRule-FSWIP.xml
- Billing Rule = FSWIP
- Billing Type = Time and Material
- Account Group = WIP
- Line Amount Formula = you can configure the necessary markup to be added on top of the WIP transaction being billed
- Use Sales Account From = Project
- Sales Subaccount Mask = JJJ-JJJ
When configuring a project and its tasks on the Projects (PM301000) form, make sure its project tasks are subject to be billed via the above configured FSWIP billing rule and allocated via CLEARUNBILLED allocation rule
Add default sales account and subaccount on the Defaults tab of the Projects (PM301000) form - we will use them in the billing rule:
Additionally, the sample project FS120 used in this example has the following project settings on the Summary tab of the Projects (PM301000) form that ease the scenario description, but can be altered as necessary:
- Run Allocation On Release of Project Transactions = True (this will allow to not bother about manually running the allocation process)
Project Billing for Appointments with UNBILLED Clearance Process Sample Flow
- On the Service Orders (FS300100) form create a service order of PBC type and add the necessary detail lines related to the sample project FS120 and project task T1, choose the necessary stock or non-stock items
- in the example provided the following lines are created: line # 1 - related to stock item ST1 (based on the assumption there are enough items available to be issued from the warehouse with this project key - please see more info on Project-Specific Inventory here: https://help-2022r2.acumatica.com/(W(8))/Help?ScreenId=ShowWiki&pageid=445cdde7-53a0-4ec4-b2d1-69496b2a504f) and line # 2 - related to the non-stock item NST1
- Click Create Appointment for the service order
- On the Appointments (FS300200) form Click Remove Hold, Start, Complete, Close, Run Billing for the generated appointment to create the following billing documents:
- Issue - it will contain a line reflecting the fact of issuing the stock item ST1 from the warehouse.
- The inventory GL batch resulting from the issue release will contain the following lines:
- 1 - Inventory asset crediting
- 2 - project related expense that has in its turn produced a related PM transaction, since the PROJECT reason code uses the account mapped to a project account group
- Project Transaction PM batch - it reflects the cost of the appointment to be billed to the customer for both stock ST1 and non-stock NST1 items
- On the Project Transaction Details (PM401000) inquiry form you will see the following transactions
- 1 - transactions from PM batch from the appointment
- 2 - transaction from the inventory issue
- 3 - transactions from the allocation process, which has been automatically run on release of the PM batch 1
- Billing is implemented via Run Project Billing. You can click Run Project Billing on the Projects (PM301000) form or use the Run Project Billing (PM503000) mass processing form to do that. A pro forma invoice or a direct AR invoice (depending on the Create Pro Forma on Billing setting of the project) will be generated.
- Release the AR invoice on the Invoices and Memos (AR30100) form
- As a result of project billing the following additional transactions will appear on the Project Transaction Details (PM401000) inquiry form:
- 4 - WIP allocation reversal transactions (automatically generated on billing the original WIP allocation transactions on AR invoice generation (in this example))
- 5 - project income REVENUE transactions
- Thus, on the project Balances tab you will have the following:
- zero on UNBILLED
- zero on WIP
- stock item expense on MATEXP
- non-stock item expense on LABOR
- income on REVENUE