How to Create Lookup by Account Type using DimensionDynamicAccountController? - forms

I have a problem.
I have in my new table two new fields
1) Name -> AccountNum, EDT--> DimensionDynamicAccount
2) Name -> AccountType, EDT--> LedgerJournalACType
class declaration
:
public class FormRun extends ObjectRun
{
DimensionDynamicAccountController dimAccountController;
}
init (for the form):
public void init()
{
super();
dimAccountController = DimensionDynamicAccountController::construct(
MyTable_ds,
fieldstr(MyTable, LedgerDimension),
fieldstr(MyTable, AccountType));
}
4. Override the following methods on the Segmented Entry control instance in the form design.
public void jumpRef()
{
dimAccountController.jumpRef();
}
public void loadAutoCompleteData(LoadAutoCompleteDataEventArgs _e)
{
super(_e);
dimAccountController.loadAutoCompleteData(_e);
}
public void segmentValueChanged(SegmentValueChangedEventArgs _e)
{
super(_e);
dimAccountController.segmentValueChanged(_e);
}
public void loadSegments()
{
super();
dimAccountController.parmControl(this);
dimAccountController.loadSegments();
}
public boolean validate()
{
boolean isValid;
isValid = super();
isValid = dimAccountController.validate() && isValid;
return isValid;
}
5. Override the following methods on the data source field that backs the Segmented Entry control.
public Common resolveReference(FormReferenceControl _formReferenceControl)
{
return dimAccountController.resolveReference();
}
Now my problem is Lookup only works for AccountType=="Ledger" not for customer, Vendor etc...
If I have a AccountType == Vendor or similant but different to Ledger I see this
I would want to have same the same thing that's in the LedgerJournalTrans Form
There is a solution,
thanks all,
enjoy

This might be too obvious, but I think you're missing the lookup() method.
See:
\Forms\LedgerJournalTransDaily\Designs\Design\[Tab:Tab]\[TabPage:OverViewTab]\[Grid:overviewGrid]\SegmentedEntry:LedgerJournalTrans_AccountNum\Methods\lookup
public void lookup()
{
if (!ledgerJournalEngine.accountNumLookup(ledgerJournalTrans_AccountNum,
ledgerJournalTrans,
ledgerJournalTrans.OffsetAccountType,
ledgerJournalTrans.parmOffsetAccount(),
ledgerJournalTrans_Asset))
{
super();
}
}

Related

GWT result state changes after dispatch

data item boolean flag won't hold its state when item is returned from server through dispatcher to Presenter (client side).
shared package
public class ResourceItem extends BaseResourceItem implements IsSerializable {
private String name;
public ResourceItem() {
super();
}
public ResourceItem(String name) {
super(true);
this.name = name;
}
}
public class BaseResourceItem {
private boolean removeEnabled = true;
public BaseResourceItem() {
super();
}
public BaseResourceItem(boolean removeEnabled) {
super();
this.removeEnabled = removeEnabled;
}
public boolean isRemoveEnabled() {
return removeEnabled;
}
public void setRemoveEnabled(boolean removeEnabled) {
this.removeEnabled = removeEnabled;
}
}
Flag in question is removeEnabled . By default it's true, and even though I set it to false in server side, when Presenter gets it, it's been set to false for some reason. Am I missing something with serialization? (can't think of anything else at this point).
Server package
#GenDispatch
public class GetModelSettings {
#Out(1)
List<ResourceItem> listOfSettings;
}
public class GetModelSettingsHandler implements ActionHandler<GetModelSettingsAction, GetModelSettingsResult> {
#Override
public GetModelSettingsResult execute(GetModelSettingsAction action, ExecutionContext context)
throws ActionException {
ResourceItem item1 = new ResourceItem();
ResourceItem item2 = new ResourceItem();
item2.setRemoveEnabled(false);
list.add(item1);
list.add(item2);
// item1 -> true
// item2 -> false
return new GetModelSettingsResult(list);
}
}
As you can see, a simple handler return a list. At this point, data is correct, one item has flag set to true, the other one to false.
Client package
public class ModelSettingsPresenter {
dispatcher.execute(new GetModelSettingsAction(), new AsyncCallback<GetModelSettingsResult>() {
#Override
public void onSuccess(GetModelSettingsResult result) {
itemList = result.getListOfSettings();
// itemList.get(0) -> true
// itemList.get(1) -> true
}
});
}
Data items both have flags set to true in this presenter. Any ideas why is this happening?
This has to do with serialization used with inheritance.
During deserialization, the fields of non-serializable classes will be initialized using the public or protected no-arg constructor of the class. A no-arg constructor must be accessible to the subclass that is serializable. The fields of serializable subclasses will be restored from the stream.
More on it can be found in different thread Java object Serialization and inheritance

How to change database schema on runtime in EF7 or EF core

My database have different schema depending on user selections on runtime.
My code is below:
public partial class FashionContext : DbContext
{
private string _schema;
public FashionContext(string schema) : base()
{
_schema = schema;
}
public virtual DbSet<Style> Styles { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder options)
{
options.UseSqlServer(#"Server=.\sqlexpress;Database=inforfashionplm;Trusted_Connection=True;");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Style>()
.ToTable("Style", schema: _schema);
}
}
Upon testing. I created a context instance with 'schema1'.
So far so good.
But when I create another context instance with different schema 'schema2', the resulting data in which the schema is still on 'schema1'.
Here is the implementation:
using (var db = new FashionContext("schema1"))
{
foreach (var style in db.Styles)
{
Console.WriteLine(style.Name);
}
}
Console.ReadLine();
Console.Clear();
using (var db = new FashionContext("schema2"))
{
foreach (var style in db.Styles)
{
Console.WriteLine(style.Name);
}
}
Console.ReadLine();
Later I noticed that the OnModelCreating is called only one time, so it is never called again when you create a new context instance of the same connection string.
Is it possible to have dynamic schema on runtime? Note: this is possible in EF6
One of possible way was mentioned above, but briefly, so I will try to explain with examples.
You ought to override default ModelCacheKeyFactory and ModelCacheKey.
ModelCachekeyFactory.cs
internal sealed class CustomModelCacheKeyFactory<TContext> : ModelCacheKeyFactory
where TContext : TenantDbContext<TContext>
{
public override object Create(DbContext context)
{
return new CustomModelCacheKey<TContext>(context);
}
public CustomModelCacheKeyFactory([NotNull] ModelCacheKeyFactoryDependencies dependencies) : base(dependencies)
{
}
}
ModelCacheKey.cs, please review Equals and GetHashCode overridden methods, they are not best one and should be improved.
internal sealed class ModelCacheKey<TContext> : ModelCacheKey where TContext : TenantDbContext<TContext>
{
private readonly string _schema;
public ModelCacheKey(DbContext context) : base(context)
{
_schema = (context as TContext)?.Schema;
}
protected override bool Equals(ModelCacheKey other)
{
return base.Equals(other) && (other as ModelCacheKey<TContext>)?._schema == _schema;
}
public override int GetHashCode()
{
var hashCode = base.GetHashCode();
if (_schema != null)
{
hashCode ^= _schema.GetHashCode();
}
return hashCode;
}
}
Register in DI.
builder.UseSqlServer(dbConfiguration.Connection)
.ReplaceService<IModelCacheKeyFactory, CustomModelCacheKeyFactory<CustomContext>>();
Context sample.
public sealed class CustomContext : TenantDbContext<CustomContext>
{
public CustomContext(DbContextOptions<CustomContext> options, string schema) : base(options, schema)
{
}
}
You can build the model externally and pass it into the DbContext using DbContextOptionsBuilder.UseModel()
Another (more advanced) alternative is to replace the IModelCacheKeyFactory to take schema into account.
I found a way to recreate the compiled model on each context creation.
public partial class MyModel : DbContext {
private static DbConnection _connection
{
get
{
//return a new db connection
}
}
private static DbCompiledModel _model
{
get
{
return CreateModel("schema name");
}
}
public MyModel()
: base(_connection, _model, false)
{
}
private static DbCompiledModel CreateModel(string schema)
{
var modelBuilder = new DbModelBuilder();
modelBuilder.HasDefaultSchema(schema);
modelBuilder.Entity<entity1>().ToTable(schema + ".entity1");
var builtModel = modelBuilder.Build(_connection);
return builtModel.Compile();
}
}

Struts 2 ModelDriven Action suporting both a list and individual items

I have inherited some struts2 REST-plugin based code, and the following construct puzzles me:
#Namespace("/merchants/{id}")
public class MerchantAction extends ActionSupport implements ModelDriven<Object> {
private Merchant merchant = new Merchant(); // A Model
private Iterable<Merchant> merchants; // A list of models
....
public HttpHeaders index() {
merchants = merchantService.findAllMerchants();
return new DefaultHttpHeaders("index");
}
#Override
public Object getModel() {
return (merchant != null ? merchant : merchants);
}
public void setId(String id) {
merchant = merchantService.findMerchant(id));
}
In other words, it seems to be toggling between returning a list and returning an individual item in the getModel() call. Is this kosher ? Looks a bit strange to me
I've considered your approach, but finally gave it up. IMO, it lost the advantage of strong typed action.
My solution is, creating a ViewModel for each action. In the view models, there can be the single model, the list of the model, and other items for pages usage, such as items for drop down list or radio buttons.
So the UserViewModel is like:
public class UserViewModel implements IViewModel<User> {
private User model;
private List<User> list;
public void setModel(User user) {
this.model = user;
}
public User getModel() {
return model;
}
public void setList(List<User> list) {
this.list = list;
}
public List<User> getList() {
return list;
}
}
And the actions are like:
public class UserController implements ModelDriven<UserViewModel> {
private int id;
private UserViewModel model = new UserViewModel();
public String index() {
return "success";
}
public String show() {
return "success";
}
public void setId(int id) {
this.id = id;
}
public int getId() {
return this.id;
}
#Override
public UserViewModel getModel() {
return model;
}
}
But in this way, I still lose the shortcut way in jsp files. I should write long model.userName instead of short userName.
I'm still finding the best solution of it.

Check if an AsyncSubject hasn't fired

AsycSubject<Unit>() sub;
// stuff
if(!sub.HasFired())
// Do stuff
Current best attempt is:
public static bool HasFired<T>(this AsyncSubject<T> sub)
{
AsyncSubject<bool> ret = new AsyncSubject<bool>();
sub.Timeout(TimeSpan.FromMilliseconds(20))
.Subscribe(_ =>
{
ret.OnNext(true);
ret.OnCompleted();
},
ex =>
{
ret.OnNext(false);
ret.OnCompleted();
});
return ret.First();
}
But it feels very ugly and long. I suspect I'm missing something simple. Any suggestions?
It's easier to wrap around the existing AsyncSubject and add the required state.
public class AsyncSubjectEx<T> : ISubject<T>, IDisposable
{
AsyncSubject<T> Subject = new AsyncSubject<T>();
public bool HasValue { get; protected set; }
public object Gate = new object();
public void OnCompleted()
{
Subject.OnCompleted();
}
public void OnError(Exception error)
{
Subject.OnError(error);
}
public void OnNext(T value)
{
lock (Gate)
{
Subject.OnNext(value);
HasValue = true;
}
}
public IDisposable Subscribe(IObserver<T> observer)
{
lock (Gate)
return Subject.Subscribe(observer);
}
public void Dispose()
{
Subject.Dispose();
}
}
Ironically, the original AsyncSubject upon reflection shows that there is a hasValue field, but it doesn't happen to be exposed. Consider reporting this to the Rx team - might be useful sometime.

passing value from activity to another in WF

I'm working with WF.
I made a custom activity called Draft_Doc:
public sealed class Draft_Doc : CodeActivity<string>
{
protected override string Execute(CodeActivityContext context)
{
C.Send_Task_Msg(unique_name, "Draft");
return "Draft";
}
}
I made another activity that contains a bookmark.
public sealed class WaitingTheApproval : NativeActivity
{
WorkflowInstanceProxy instance;
Service1Client C = new Service1Client();
public InArgument<string> previous_stage { get; set; }
public string stageName;
protected override void CacheMetadata(NativeActivityMetadata metadata)
{
base.CacheMetadata(metadata);
metadata.AddDefaultExtensionProvider<MyExtension>(() => new MyExtension());
//RuntimeArgument argSql = new RuntimeArgument("SqlConnectionString", typeof(String), ArgumentDirection.In);
}
protected override bool CanInduceIdle
{
get { return true; }
}
protected override void Execute(NativeActivityContext context)
{
var bookmark = context.CreateBookmark("MyBookmark", BookmarkResumed);
var extension = context.GetExtension<MyExtension>();
instance = extension._instance;
stageName = context.GetValue(this.previous_stage);
stageName = previous_stage.Get(context);
WaitSome(bookmark);
}
}
What I want is, when I drag and drop these two activities in rehosted workflow. I want to drag Draft_Doc first then I will link the WaitingTheApproval with it.
So, I want the return value from Draft_Doc set in the InArgument previous_stage in WaitingTheApproval at runtime.
Anyhelp?
There is no way to pass a value from one activity to another directly. you should assign the value to a Variable in the first activity and use the variable which has been assigned in the second activity.