Code Contracts Invariant unproven.. Works fine with Contract.Assert at the end of each method - code-contracts

I'm hoping someone can help me..
I have a C# class in which I have implemented a Code Contracts invariant. My methods keep throwing "invariant unproven" errors unless I explicitly assert the invariant is true.
My suspicion is that the problem derives from the use of void return type?
[ContractInvariantMethod]
private void FooInvariant()
{
Contract.Invariant(!(Foo1.GetState() == "failed") || (Foo2.Get_State() == "off"));
}
//this method works fine
public void FooBar()
{
Foo1.IncreaseInternalInt();
Contract.Assert(!(Foo1.GetState() == "failed") || (Foo2.Get_State() == "off"));
}
//As does this method
public void FooBarTwo()
{
Contract.Assert(!(Foo1.GetState() == "failed") || (Foo2.Get_State() == "off"));
Foo1.IncreaseInternalInt();
}
//This method doesn't work
public void FooBarThree()
{
Contract.Requires(!(Foo1.GetState() == "failed") || (Foo2.Get_State() == "off"));
Foo1.IncreaseInternalInt();
}
//This method doesn't work either
public void FooBarFour()
{
Contract.Ensures(!(Foo1.GetState() == "failed") || (Foo2.Get_State() == "off"));
Foo1.IncreaseInternalInt();
}
I hope I haven't dumbed this down too much.
Any help would be greatly appreciated!

Related

Acumatica 2021 R2 Override Create Sales Order

Acumatica seems to have moved the CreateSalesOrder method from OpportunityMaint to the new CRCreateSalesOrder class. I cannot figure out how to override the CreateSalesOrder method with the new structure. Below is the original code. Any help greatly appreciated.
using PX.Data;
using PX.Objects.AR;
using PX.Objects.CM;
using PX.Objects.Common.Discount;
using PX.Objects.CR;
using PX.Objects.CR.Extensions.CRCreateSalesOrder;
using PX.Objects.CS;
using PX.Objects.IN;
using PX.Objects.PO;
using PX.Objects.SO;
using PX.Objects.TX;
using System.Collections.Generic;
using static PX.Objects.CR.OpportunityMaint;
namespace CH.KV.CPLVendorSOPO
{
public class CHKVOpportunityMaintExt : PXGraphExtension<OpportunityMaint>
{
public delegate void DoCreateSalesOrderDelegate(CreateSalesOrderFilter param);
[PXOverride]
public void DoCreateSalesOrder(CreateSalesOrderFilter param, DoCreateSalesOrderDelegate baseMethod)
{
DoCreateSalesOrderCHKVExt(param);
}
protected virtual void DoCreateSalesOrderCHKVExt(CreateSalesOrderFilter param)
{
bool recalcAny = param.RecalculatePrices == true ||
param.RecalculateDiscounts == true ||
param.OverrideManualDiscounts == true ||
param.OverrideManualDocGroupDiscounts == true ||
param.OverrideManualPrices == true;
var opportunity = Base.Opportunity.Current;
Customer customer = (Customer)PXSelect<Customer, Where<Customer.bAccountID, Equal<Current<CROpportunity.bAccountID>>>>.Select(Base);
//do things
docgraph.Save.Press();
}
}
}
You have to add the CRCreateSalesOrder extension class and overwrite the DoCreateSalesOrder method in there. This works on Acumatica 2022R2. Not sure of 2021R2.
public class CRCreateSalesOrderExt : CRCreateSalesOrder<OpportunityMaint.Discount, OpportunityMaint, CROpportunity>
{
#region Initialization
public static bool IsActive() => IsExtensionActive();
protected override DocumentMapping GetDocumentMapping()
{
return new DocumentMapping(typeof(CROpportunity))
{
QuoteID = typeof(CROpportunity.quoteNoteID)
};
}
#endregion
#region Events
public virtual void _(Events.RowSelected<CROpportunity> e)
{
CROpportunity row = e.Row as CROpportunity;
if (row == null) return;
CRQuote primaryQt = Base.PrimaryQuoteQuery.SelectSingle();
bool hasProducts = Base.Products.SelectSingle() != null;
var products = Base.Products.View.SelectMultiBound(new object[] { row }).RowCast<CROpportunityProducts>();
bool allProductsHasNoInventoryID = products.Any(_ => _.InventoryID == null) && !products.Any(_ => _.InventoryID != null);
bool hasQuotes = primaryQt != null;
CreateSalesOrder
.SetEnabled(hasProducts && !allProductsHasNoInventoryID
&& (
(!hasQuotes
|| (primaryQt.Status == CRQuoteStatusAttribute.Approved
|| primaryQt.Status == CRQuoteStatusAttribute.Sent
|| primaryQt.Status == CRQuoteStatusAttribute.Accepted
|| primaryQt.Status == CRQuoteStatusAttribute.Draft
)
)
)
&& (!hasQuotes || primaryQt.QuoteType == CRQuoteTypeAttribute.Distribution)
&& e.Row.BAccountID != null);
}
#endregion
#region Overrides
public override CRQuote GetQuoteForWorkflowProcessing()
{
return Base.PrimaryQuoteQuery.SelectSingle();
}
public override void DoCreateSalesOrder(SOOrderEntry docgraph, Extensions.CRCreateSalesOrder.Document masterEntity, CreateSalesOrderFilter filter)
{
base.DoCreateSalesOrder(docgraph, masterEntity, filter);
}
#endregion
}
You will need to find where the code was moved too. I have had to do something similar when acumatica shifted up some buttons within the Customer Payment Profile Maint Graph into its own dedicated class.
This is what the new graph extension declaration looked like I'm my case where the original was a direct extension of the Customer Payment Profile Maint Graph
public class APSPaymentProfileHostedFormExtension : PXGraphExtension<
CustomerPaymentMethodMaint.PaymentProfileHostedForm,
CustomerPaymentMethodMaint>
{
For clues, you want to look for something like this that will be declared on the graph the button originally resided. In my case, it looked like this.
public class PaymentProfileHostedForm : Extensions.PaymentProfile.PaymentProfileGraph<CustomerPaymentMethodMaint, CustomerPaymentMethod>
{
Hopefully, this is enough to get you in the right direction. Let me know how you make out?

Customer Persist Override gives NextMove issue while deleting

I am getting the following error when trying to delete a customer:
An unhandled exception has occurred in the function 'MoveNext'
I think i need to add this if statement or something similar.
if(Base.BAccount.Cache.GetStatus(CCustomer) != PXEntryStatus.InsertedDeleted || Base.BAccount.Cache.GetStatus(CCustomer) != PXEntryStatus.Deleted)
I found a couple of links with this issue but non that is specific to the customer page.
public delegate void PersistDelegate();
[PXOverride]
public void Persist(PersistDelegate baseMethod)
{
using (var scope = new PXTransactionScope())
{
Customer row = this.Base.BAccount.Current;
if (row.ParentBAccountID == null)
{
CustomerMaint businessAccount = PXGraph.CreateInstance<CustomerMaint>();
PXResultset<Customer> Children = PXSelect<Customer, Where<Customer.parentBAccountID, Equal<Required<Customer.bAccountID>>>>.Select(Base, row.BAccountID);
foreach (Customer item in Children)
{
businessAccount.Clear();
businessAccount.BAccount.Current = PXSelectorAttribute.Select<Customer.bAccountID>(this.Base.BAccount.Cache, item.BAccountID) as Customer;
item.TermsID = row.TermsID;
item.Status = row.Status;
Contact defContact = PXSelect<Contact, Where<Contact.bAccountID, Equal<Required<BAccount.bAccountID>>, And<Contact.contactID, Equal<Required<BAccount.defContactID>>>>>.Select(businessAccount, item.BAccountID, item.DefContactID);
defContact.EMail = this.Base.DefContact.Current.EMail;
businessAccount.DefContact.Update(defContact);
businessAccount.BAccount.Update(item);
businessAccount.Save.PressButton();
}
}
baseMethod();
scope.Complete();
}
}
I am hoping there is a check I can build in or something that can eliminate the MoveNext error when deleting.
Try to use the same pattern as the base CustomerMaint class which uses UpdateChildAccounts and GetChildAccounts methods to modify the child accounts.
protected virtual void Customer_PrintDunningLetters_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
Customer row = (Customer)e.Row;
CheckExcludedFromDunning(cache, row);
UpdateChildAccounts<Customer.printDunningLetters>(cache, row, GetChildAccounts(sharedCreditPolicy: true));
}
protected virtual void Customer_Status_FieldUpdated(PXCache cache, PXFieldUpdatedEventArgs e)
{
Customer row = e.Row as Customer;
if (row == null) return;
if (row.ParentBAccountID == null)
{
Func<Customer, bool> func;
string newValue = GetSharedCreditChildStatus(row.Status, out func);
UpdateChildAccounts<Customer.status>(cache, row, GetChildAccounts(sharedCreditPolicy: true).Where(func), newValue);
}
}
protected virtual void Customer_ConsolidateToParent_FieldUpdated(PXCache sender, PXFieldUpdatedEventArgs e)
{
Customer row = (Customer)e.Row;
if (row == null) return;
if (row.ParentBAccountID == null)
{
IEnumerable<Customer> childs;
string message = PXMessages.LocalizeFormatNoPrefix(Messages.RelatedFieldChangeOnParentWarning,
PXUIFieldAttribute.GetDisplayName<Customer.consolidateToParent>(sender));
if ((childs = GetChildAccounts()).Any() && e.ExternalCall)
{
if (CurrentCustomer.Ask(message, MessageButtons.YesNo) == WebDialogResult.Yes)
{
UpdateChildAccounts<Customer.consolidateToParent>(sender, row, childs);
}
}
row.SharedCreditPolicy &= row.ConsolidateToParent;
}
else if (row.SharedCreditPolicy == true && row.ConsolidateToParent != true && (bool?)e.OldValue == true)
{
sender.SetValueExt<Customer.sharedCreditPolicy>(row, false);
}
}
protected virtual void UpdateChildAccounts<Field>(PXCache cache, Customer parent, IEnumerable<Customer> enumr, object sourceValue = null)
where Field : IBqlField
{
if (PXAccess.FeatureInstalled<FeaturesSet.parentChildAccount>() &&
parent != null &&
parent.ParentBAccountID == null)
{
sourceValue = sourceValue ?? cache.GetValue<Field>(parent);
foreach (Customer child in enumr)
{
if (sourceValue != cache.GetValue<Field>(child))
{
cache.SetValue<Field>(child, sourceValue);
cache.Update(child);
}
}
}
}
protected virtual IEnumerable<Customer> GetChildAccounts(bool sharedCreditPolicy = false, bool consolidateToParent = false, bool consolidateStatements = false)
{
if (PXAccess.FeatureInstalled<FeaturesSet.parentChildAccount>())
{
PXSelectBase<Customer> select = new PXSelect<Customer, Where<Customer.parentBAccountID, Equal<Current<Customer.bAccountID>>>>(this);
if (sharedCreditPolicy)
{
select.WhereAnd<Where<Customer.sharedCreditPolicy, Equal<True>>>();
}
if (consolidateToParent)
{
select.WhereAnd<Where<Customer.consolidateToParent, Equal<True>>>();
}
if (consolidateStatements)
{
select.WhereAnd<Where<Customer.consolidateStatements, Equal<True>>>();
}
return select.Select().RowCast<Customer>();
}
return Enumerable.Empty<Customer>();
}
Otherwise create a new DAC inheriting from Customer to hold the children and create a data view for them in the graph. You can then modify the children in that data view and they will be persisted automatically when user invoke the Save action from UI.
[Serializable]
public partial class OtherCustomer : Customer
{
public new abstract class bAccountID : PX.Data.BQL.BqlInt.Field<bAccountID> { }
}
PXSelect<OtherCustomer, Where< … >> OtherCustomers;

How to set default value of UITypeEditor

I have this property of a custom object to be displayed in a PropertyGrid:
[DisplayName("Dirección IP Local")]
[Editor(typeof(Configuracion.Editors.IPAddressEditor), typeof(UITypeEditor))]
[Description("Dirección IP del computador en el cual está conectado el dispositivo.")]
public IPAddress IPLocal { get; set; }
In constructor of the same class I have:
this.IPLocal = Common.Helper.ProgramInfo.GetLocalIPAddresses().FirstOrDefault();
The IPAddressEditor is this:
public class IPAddressEditor : UITypeEditor
{
private IWindowsFormsEditorService _editorService;
private IpAddressInput _ipAddressInput;
private bool _escKeyPressed;
public IPAddressEditor()
{
_ipAddressInput = new IpAddressInput();
_ipAddressInput.Width = 150;
_ipAddressInput.BackgroundStyle.BorderWidth = -1;
_ipAddressInput.ButtonClear.Visible = true;
_ipAddressInput.ValueChanged += _ipAddressInput_ValueChanged;
_ipAddressInput.PreviewKeyDown += _ipAddressInput_PreviewKeyDown;
}
void _ipAddressInput_PreviewKeyDown(object sender, System.Windows.Forms.PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Escape)
_escKeyPressed = true;
}
void _ipAddressInput_ValueChanged(object sender, EventArgs e)
{
if (_editorService != null)
_editorService.CloseDropDown();
}
public override UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
if (provider != null)
{
_editorService =
provider.GetService(
typeof(IWindowsFormsEditorService))
as IWindowsFormsEditorService;
}
if (_editorService != null)
{
_escKeyPressed = false;
_editorService.DropDownControl(_ipAddressInput);
if (!_escKeyPressed)
{
IPAddress ip = IPAddress.None;
if (IPAddress.TryParse(_ipAddressInput.Value, out ip))
return ip;
}
}
return value;
}
}
The problem is that the control inside the editor (in this case _ipAddressInput) is not initialized with the value I assigned in object constructor.
This is obvious because in type editor constructor I am creating a new instance of IpAddressInput, so the question is: what is the best way to initialize it?
I was thinking about creating a public setter for that variable and calling in constructor of the custom object using a TypeDescriptor, but I think this is tricky,
Is there a better solution?
Regards
Jaime
Finally, I have found the solution.
I just added
_ipAddressInput.Text = value.ToString();
before the call to
_editorService.DropDownControl(_ipAddressInput);
I have thought about it before but I underestimate it because I was wondering what will happen when updating the property using the editor and whether it will keep the modified value.It was no problem with that and the editor worked like a charm.

SelectItemsConverter Omnifaces preselected from database

I have a problem: When I save my object to the DB it works fine, but when I want to retrieve it from the DB, it doesn't work. I'm using selectItemsConverter from Omnifaces 1.8.3 (I tried with 1.10 too)
AutomacaoEmail.java
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
...
#ManyToOne(fetch = FetchType.EAGER)
private ModeloEmail modeloEmail;
...
#Override
public int hashCode() {
int hash = 7;
hash = 31 * hash + Objects.hashCode(this.id);
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final AutomacaoEmail other = (AutomacaoEmail) obj;
if (!Objects.equals(this.id, other.id)) {
return false;
}
return true;
}
#Override
public String toString() {
return String.format("%s[id=%d]", getClass().getSimpleName(), getId());
}
loadFromDatabaseMethod()
List<ModeloEmail> modelosTemp = modeloEmailFacade.buscarTodos();
SelectItemsBuilder selectItemsBuilder = new SelectItemsBuilder();
if (modelosTemp != null) {
for (ModeloEmail modeloEmail : modelosTemp) {
selectItemsBuilder.add(modeloEmail, modeloEmail.getNome());
}
modelosEmails = selectItemsBuilder.buildList();
}
page.xhtml
<p:selectOneMenu value="#{automacaoEmailsController.automacaoEmail.modeloEmail}" converter="omnifaces.SelectItemsConverter">
<f:selectItem noSelectionOption="true" itemLabel="Selecionar um modelo"/>
<f:selectItems value="#{automacaoEmailsController.modelosEmails}"/>
</p:selectOneMenu>
I tried with SelectItemsIndexConverter too.
if (getClass() != obj.getClass()) {
return false;
}
This test in your equals() method may fail when obj is a JPA implementation specific proxy class, such as used by Hibernate for e.g. lazy entities. That would at least explain why it seem to "sometimes" work.
If you're indeed using Hibernate, then you'd need to replace the above test by below test:
if (Hibernate.getClass(this) != Hibernate.getClass(obj)) {
return false;
}
Or by the below more generic (not Hibernate-dependent) test:
if (!(obj.getClass().isAssignableFrom(getClass()) && getClass().isAssignableFrom(obj.getClass()))) {
return false;
}

How to stop Thread in other function

I have a game with thread. I new this thread in function StartGame() and I want stop this thread at function GameOver(). How can do it?
First of all, code would help answer the question. However, What you can do is something like(if I even understand what you are asking):
boolean running = false;
public void StartGame()
if (thread !== null)
{
thread= new Thread(this) <-------(if your class implements Runnable)
running = true
thread.start();
}
public void run()
{
while(running){
//Code you want to execute
EndGame()
}
public void EndGame()
{
if (thread == null)
{
return;
}
else
running = false;
//anything else you want to do (exit, any other methods, etc.)
}

Resources