Create Sales Order Payment in 2020R2 - acumatica

I'm upgrading a customization that was able to create payments on Sales Orders via code. Prior to 2020R2 I could use something along the lines of...
PXGraph graph;
orderEntry.CreatePaymentProc(orderEntry.Document.Current, out graph);
ARPaymentEntry paymentEntry = (ARPaymentEntry)graph;
ARPayment payment = paymentEntry.Document.Select();
payment.PaymentMethodID = ...;
payment.CuryOrigDocAmt = ...;
payment.ExtRefNbr = ...;
payment.CashAccountID = ...;
paymentEntry.Document.Update(payment);
paymentEntry.Actions.PressSave();
As of Acumatica 2020R2 CreatePaymentProc is no longer a method of SOOrderEntry.
How can the same result be achieved?

The full solution here involved a couple additional method calls...
SOOrder order = orderEntry.Document.Current;
CreatePaymentExt createPaymentExt = orderEntry.GetExtension<CreatePaymentExt>();
SOQuickPayment payment = createPaymentExt.QuickPayment.Current;
createPaymentExt.SetDefaultValues(payment, order);
payment.PaymentMethodID = ...;
payment.CuryOrigDocAmt = ...;
payment.ExtRefNbr = ...;
payment.CashAccountID = ...;
ARPaymentEntry paymentEntry = createPaymentExt.CreatePayment(payment, order, ARPaymentType.Payment);
paymentEntry.Save.Press();

All of the methods and actions for the payment creating for the Sales Orders records in the Acumatica 2020R2 release you can find in the extension CreatePaymentExtclass.
As of Acumatica 2020R2 CreatePaymentProc has been changed the CreatePayment method on the CreatePaymentExt class.

Related

How to Create a Purchase Receipt with Document Details via code

The Goal is creating a Purchase Order and then its corresponding Purchase Order receipt via code with 2 separate actions/buttons.
The PO (Type Normal) is created without any issues. And is then Approved via code making it visible in the "Add Purchase Order" smartpanel from the Purchase Receipt page.
The UI workflow would be the selection of the PO order and then pressing on "ADD PO".
I'm looking to replicate that via code.
Looking at the page's ASPX definition I can see that the smartpanel button is associated to action AddPOOrder2
I'm creating the Purchase receipt like this:
if (orderRecord.Approved == true)
{
poReceiptEntryGraph = PXGraph.CreateInstance<POReceiptEntry>();
receiptRow = new POReceipt();
//Summary
receiptRow.ReceiptType = "RT";
receiptRow = poReceiptEntryGraph.Document.Insert(receiptRow);
receiptRow.Hold = false;
receiptRow.ReceiptDate = DateTime.Now;
receiptRow.VendorID = orderRecord.VendorID;
receiptRow.InvoiceNbr = "123";
poReceiptEntryGraph.Document.Update(receiptRow);
poReceiptEntryGraph.Actions.PressSave();
Then I create a PXView:
int startActualRow = PXView.StartRow;
int totalActualRows = 1;
List<Object> createdView = new PXView(poReceiptEntryGraph, false, PXSelect<POOrder, Where<POOrder.orderNbr, Equal<Required<POOrder.orderNbr>>>>
.GetCommand()).Select(PXView.Currents, /*Filter value from the BQL Required*/ new object[] { "PO000683"/*orderRecord.OrderNbr*/ },
PXView.Searches, PXView.SortColumns, PXView.Descendings, PXView.Filters,
ref startActualRow, PXView.MaximumRows, ref totalActualRows);
PXView dummyActualView = new DummyView(poReceiptEntryGraph, poReceiptEntryGraph.Document.View.BqlSelect, createdView);
Finally, the PXView is used to press on the AddPOOrder2 action:
poReceiptEntryGraph.addPOOrder2.Press(new PXAdapter(dummyActualView));
poReceiptEntryGraph.Actions.PressSave();
No error messages are received and the summary section of the Receipt gets created correctly but without any content in the grid.
I also attempted to use addPOOrder which is another Acumatica action that executes addPOOrder2 but the result was the same.
Any ideas if I'm missing something?
Thanks.
I found the solution for this.
Acumatica's AddPOOrder2 action iterates over the selected records and invokes method AddPurchaseOrder
Invoking the method directly in my action worked correctly:
if (orderRecord.Approved == true)
{
poReceiptEntryGraph = PXGraph.CreateInstance<POReceiptEntry>();
receiptRow = new POReceipt();
receiptRow.ReceiptType = "RT";
receiptRow = poReceiptEntryGraph.Document.Insert(receiptRow);
receiptRow.Hold = false;
receiptRow.ReceiptDate = DateTime.Now;
receiptRow.VendorID = orderRecord.VendorID;
poReceiptEntryGraph.Document.Update(receiptRow);
poReceiptEntryGraph.Actions.PressSave();
poReceiptEntryGraph.AddPurchaseOrder(orderRecord);
poReceiptEntryGraph.Actions.PressSave();
}
However, I wonder, had the method not existed, was I in the correct path with the use of the PXView and the PXAdapter? Is it possible to execute other similar actions that may not have a method?

Creating detail view of doors in Revit api

How to create detail view in Revit of specific door using Revit API( external command)? For now I managed to create DetailView, but when I open in Revit that view it is not what I expected(see images: expected , what I get).
Here is the code:
IEnumerable<ViewFamilyType> viewFamilyTypes = from elem in new FilteredElementCollector(doc).OfClass(typeof(ViewFamilyType))
let type = elem as ViewFamilyType
where type.ViewFamily == ViewFamily.Detail
select type;
//uiDoc.Selection.SetElementIds(new List<ElementId>() { door.Id });
var dim = door.get_BoundingBox(null);
using (Transaction transaction = new Transaction(doc))
{
transaction.Start("Creating Detail View");
BoundingBoxXYZ box = dim;
var detailView = ViewSection.CreateDetail(doc,viewFamilyTypes.First().Id, box);
detailView.Discipline = ViewDiscipline.Architectural;
detailView.DetailLevel = ViewDetailLevel.Coarse;
transaction.Commit();
}
I'm using Revit 2018,
Any help or suggestion is welcome just to finish my student research.
Do The Building Coder articles on creating a section view help?

How to Speed Up Contract API CustomerID Search?

I'm trying to search the existing Customers and return the CustomerID if it exists. This is the code I'm using which works:
var CustomerToFind = new Customer
{
MainContact = new Contact
{
Email = new StringSearch { Value = emailIn }
}
};
var sw = new Stopwatch();
sw.Start();
//see if any results
var result = (Customer)soapClient.Get(CustomerToFind);
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
However, I've finding it appears extremely slow to the point of being unusable. For example on the DEMO dataset, on my i7-6700k # 4GHz with 24gb ram and SSD running SQL Server 2016 Developer Edition locally a simple email search takes between 3-4seconds. However on my production dataset with 10k Customer records, it takes over 60 seconds and times out.
Is this typical using Contract based soap? Screen based soap seems much faster and almost instant. If I perform a SQL select on the database tables in Microsoft Management Studio I can also return the result instantly.
Is there a better quick way to query if a Customer with email address = "test#test.com" exists and return the Customer ID?
Try using GetList instead of Get. It's better suited for "search for smth" scenarios.
When using GetList, depending on which endpoint you're using, there are two more optimizations. In Default/5.30.001 endpoint there's a second parameter to GetList which you should set to false. In Default/6.00.001 endpoint there's no second parameter but there is additional property in the entity itself, called ReturnBehavior. Either set it to OnlySpecified and then add *Return to required fields, like this:
var CustomerToFind = new Customer
{
ReturnBehavior = ReturnBehavior.OnlySpecified,
CustomerID = new StringReturn(),
MainContact = new Contact
{
Email = new StringSearch { Value = emailIn }
}
};
or set it to OnlySystem and then use ID on returned entity to request the full entity.

"Order By" When Retrieving From Acumatica Web Service API

I was wondering if there was a way to add an "Order By" clause when retrieving data from Acumatica through the Web Service API?
IN202500Content IN202500 = oScreen.IN202500GetSchema();
oScreen.IN202500Clear();
Command[] oCmd = new Command[] {IN202500.StockItemSummary.ServiceCommands.EveryInventoryID,
IN202500.StockItemSummary.InventoryID,
IN202500.StockItemSummary.Description,
IN202500.StockItemSummary.ItemStatus,
IN202500.GeneralSettingsItemDefaults.ItemClass,
IN202500.GeneralSettingsItemDefaults.LotSerialClass,
IN202500.PriceCostInfoPriceManagement.DefaultPrice,
};
Filter[] oFilter = new Filter[] {new Filter
{
Field = new Field {ObjectName = IN202500.StockItemSummary.InventoryID.ObjectName,
FieldName = "LastModifiedDateTime"},
Condition = FilterCondition.GreaterOrEqual,
Value = SyncDate
}
};
String[][] sReturn = oScreen.IN202500Export(oCmd, oFilter, iMaxRecords, true, false);
I would like to sort the results for example by DefaultPrice, so that I can retrieve the Top 200 most expensive items in my list (using iMaxRecords = 200 in this case)
I haven't seen any parameters that allows me to do the sorting yet.
I ran into this when I developed a round robin assignment system and the short answer is using the Acumatica API you cant do a sort on the results you have to do it outside of the API (This info came from a friend closely tied to the Acumatica product).
I came up with two options:
Query your DB directly... There are always reasons not to do this but it is much faster than pulling the result from the API and will allow you to bypass the BQL Acumatica uses and write an SQL statement that does EXACTLY what you want providing a result that is easier to work with than the jagged array Acumatica sends.
You can use some Linq and build a second array[][] that is sorted by price and then trim it to the top 200 (You would need all results from Acumatica first).
// This is rough but should get you there.
string[][] MaxPriceList = sReturn.OrderBy(innerArray =>
{
if () // This is a test to make sure the element is not null
{
decimal price;
if (//test decimal is not null))
return price;
}
return price.MaxValue;
}).Take(200).ToArray(); //Take 200 is a shot but might work

Invoice record adding in netsuite

I have an issue.
Please help me when I add the invoice in NetSuite it's given me a
error:[code] => USER_ERROR [message] => Please enter value(s) for: Department, Class, Warehouse
Can any one tell me how can generate NetSuite invoice via API.
$inv=new Invoice();
$customFormR=new RecordRef();
$customFormR->internalId =104;
//'1 Aquatic Fitness Concepts'
$inv_items= new InvoiceItem();
$itemRR = new RecordRef();
$itemRR->internalId = 25;
$itemRR->recordType = "inventoryItem";
$inv_items->item=$itemRR;
$location=new RecordRef();
$location->internalId =2;
$inv_items->location=$location;
$departmentRR=new RecordRef();
$departmentRR->internalId =6;
$inv_items->department=$departmentRR;
$classRR=new RecordRef();
$classRR->internalId =22;
$inv_items->class=$classRR;
$inv_it_list=new InvoiceItemList();
$inv_it_list->item=array($inv_items);
$inv->itemList= $inv_it_list;
$inv->entity = new RecordRef();
$inv->entity->internalId = 932;
//$inv->entity
$inv->customForm=$customFormR;
$request = new AddRequest();
$request->record = $inv;
$addResponse = $service->add($request);
if (!$addResponse->writeResponse->status->isSuccess) {
echo "ADD ERROR";
print_r($addResponse);
exit();
} else {
echo "ADD SUCCESS, id " . $addResponse->writeResponse->baseRef->internalId;
}
In NetSuite, you have the option of setting Location, Department, Class at the header level as a default, and on the line level as an override of the default.
Take a look at how Location, Department, Class are set up for transactions in your NetSuite account. Your code shows you are trying to set these fields at the line item level. If the option to specify them on the line level is not enabled (Setup->Accounting->Accounting Preferences->General), you should not be able to set them on the line level.
Try setting those fields on the header level. For example:
$inv->department = $departmentRR;

Resources