platform icon indicating copy to clipboard operation
platform copied to clipboard

INTERNAL actions, client-server

Open hernad opened this issue 5 years ago • 3 comments

I am trying to understand how fiscal functions works.

Let us take as example this lsfusion code:

MODULE FiscalVMK;
REQUIRE CashRegister;

loadDefaultCashRegisterModels() + {EXEC loadDefaultCashRegisterModel ('VMK fiscal registrar', 'VMK', NULL, NULL, TRUE, NULL, NULL); };

isUnix = osVersion (currentComputer()) == 'Linux';
needDLL() = GROUP SUM 1 IF computer (CashRegister c) == currentComputer () AND sidModel (groupMachinery (c)) == 'VMK';
onDesktopClientStarted() + {
    IF needDLL () THEN {
         IF isUnix () THEN {
                loadLibrary ('lib/ux64/libvmkd.so');
        } ELSE {
              IF is64Java (currentComputer ()) THEN
                   loadLibrary ('lib/win64/vmkd.dll');
              ELSE
                loadLibrary ('lib/win32/vmkd.dll');
       }
    }
};
setFiscalNumber 'Write Z-report number' ABSTRACT (STRING[28]);
closeCurrentZReport 'Close current Z-report' ABSTRACT ();
fiscalVMKReceiptTitle 'VMK receipt title' = ABSTRACT TEXT ();
fiscalVMKPrintCopyReceipt 'Copy of receipt' INTERNAL 'lsfusion.erp.region.by.machinery.cashregister.fiscalvmk.FiscalVMKPrintCopyReceiptAction' ();
....

I am running desktop (swing) client. I suppose that onDesktopClientStarted() is executed on client.

But where is executed referenced java class?

package lsfusion.erp.region.by.machinery.cashregister.fiscalvmk;

import com.google.common.base.Throwables;
import lsfusion.interop.action.MessageClientAction;
import lsfusion.server.physics.admin.log.ServerLoggers;
import lsfusion.server.data.sql.exception.SQLHandledException;
import lsfusion.server.physics.dev.integration.internal.to.InternalAction;
import lsfusion.server.logics.property.classes.ClassPropertyInterface;
import lsfusion.server.logics.action.controller.context.ExecutionContext;
import lsfusion.server.language.ScriptingErrorLog;
import lsfusion.server.language.ScriptingLogicsModule;

import java.sql.SQLException;

public class FiscalVMKPrintCopyReceiptAction extends InternalAction {

    public FiscalVMKPrintCopyReceiptAction(ScriptingLogicsModule LM) {
        super(LM);

    }

    public void executeInternal(ExecutionContext context) throws SQLHandledException {

        try {

            boolean isUnix = findProperty("isUnix[]").read(context) != null;
            String logPath = (String) findProperty("logPathCurrentCashRegister[]").read(context);
            String ip = (String) findProperty("ipCurrentCashRegister[]").read(context);
            String comPort = (String) findProperty("stringComPortCurrentCashRegister[]").read(context);
            Integer baudRate = (Integer) findProperty("baudRateCurrentCashRegister[]").read(context);

            String result = (String) context.requestUserInteraction(new FiscalVMKPrintCopyReceiptClientAction(isUnix, logPath, ip, comPort, baudRate));
            if (result != null) {
                ServerLoggers.systemLogger.error("FiscalVMKPrintCopyReceipt Error: " + result);
                context.requestUserInteraction(new MessageClientAction(result, "Ошибка"));
            }

        } catch (SQLException | ScriptingErrorLog.SemanticErrorException e) {
            throw Throwables.propagate(e);
        }


    }
}

On application server? No we don't want that. This java class should be executed on client side. Ok, I will suppose that also :).

But there are cases when we want to run some java code on server side. How to do that? Treating that as external system?

In the context of fiscal functions and similar tasks that are needed to be executed client side, I suppose there is no solution to do such tasks with web client. Am I right?

hernad avatar Oct 08 '20 09:10 hernad

Regarding this topic, this is also interesting module:

MODULE WeightDaemon;

REQUIRE SystemEvents;

scalesComPort 'Com-port scales' = DATA INTEGER (Computer);
EXTEND FORM computer PROPERTIES(c) scalesComPort;
EXTEND FORM computers PROPERTIES(c) READONLY scalesComPort;
EXTEND FORM computersDialog PROPERTIES(c) READONLY scalesComPort;

weightDaemon  INTERNAL  'lsfusion.erp.daemon.WeightDaemonAction' (INTEGER);
onDesktopClientStarted() + {
    weightDaemon(scalesComPort(currentComputer()));
}

hernad avatar Oct 08 '20 10:10 hernad

INTERNAL action are executed on the server side. However there is a requestUserAction method (of execution context) that does some magic. You can pass there an object of some java class (on server !) that extends ClientAction class, and the platform will transfer it to the client (using slightly modified java class loader) and will execute this action there. Now it works only for desktop-client (in web it only goes to the web-server and an exception is raised there), but since in 4 version there is a new functionality (you can put some javascript / css files in web subfolder of an application server and platform will load / run this files in web-client, i.e browser), I think will add some field with the name of some javascript function to this ClientAction and it will be executed in web client. Of course it that case you should write separate actions for web and desktop client, but it's better than nothing. The perfect solution would be to use GWT to transpile java code to javascript code, but I'm not sure that it's technically possible. And also if the desktop client is considered to be deprecated in future, problem will eventually disappear by itself.

AlexKirkouski avatar Oct 09 '20 08:10 AlexKirkouski

GWT to transpile java code to javascript code, but I'm not sure that it's technically possible

I don't think that would fork anyway for most use cases. If we want to access local filesystem or local device (e.g. serial port) web client cannot use it.

hernad avatar Oct 09 '20 08:10 hernad