package {{packageName}}.core.{{entity.module}}.service.impl;

{{#each entity.allPSDEMethodDTOs as |deMethodDTO|}}
    {{#if (or (eq deMethodDTO.type 'DEFAULT') (eq deMethodDTO.type 'DEACTIONINPUT'))}}
import {{packageName}}.core.{{entity.module}}.dto.{{deMethodDTO.name}};
    {{/if}}
{{/each}}
import net.ibizsys.central.dataentity.service.DEServiceBase;
import net.ibizsys.central.dataentity.service.IDEService;
import net.ibizsys.central.r8.IR8SystemGateway;
import {{packageName}}.core.runtime.ISystemRuntime;
import net.ibizsys.model.dataentity.action.IPSDEAction;
import net.ibizsys.central.util.SearchContextDTO;
import net.ibizsys.model.dataentity.ds.IPSDEDataSet;
import net.ibizsys.runtime.dataentity.DataEntityRuntimeException;
import net.ibizsys.runtime.dataentity.IDataEntityRuntimeContext;
import net.ibizsys.runtime.dataentity.action.IDEActionPluginRuntime;
import net.ibizsys.runtime.dataentity.ds.IDEDataSetPluginRuntime;
import net.ibizsys.runtime.util.ActionSessionManager;
import net.ibizsys.runtime.util.Errors;
import net.ibizsys.runtime.util.IAction;
import net.ibizsys.runtime.util.ITransactionalUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.List;

@Service
public class {{entity.codeName}}ServiceImpl extends DEServiceBase<{{entity.defaultPSDEMethodDTO.name}}, SearchContextDTO> implements {{packageName}}.core.{{entity.module}}.service.I{{entity.codeName}}Service {


    @Autowired(required = false)
    IR8SystemGateway systemGateway;

    ISystemRuntime iSystemRuntime;

    @Override
    public ISystemRuntime getSystemRuntime() {
        if (this.iSystemRuntime == null)
            this.iSystemRuntime = systemGateway.getSystemRuntime(ISystemRuntime.class, false);
        return this.iSystemRuntime;
    }

    @PostConstruct
    private void postConstruct() throws Exception {
        if (systemGateway != null && !systemGateway.isMultiSystemMode()) {
            try {
                IDEService iDEService = systemGateway.getDEService("{{packageName}}.core.runtime.ISystemRuntime", this.getDataEntityId());
                if(iDEService.getClass() == {{entity.codeName}}ServiceImpl.class)
                    systemGateway.registerDEService("{{packageName}}.core.runtime.ISystemRuntime", this.getDataEntityId(), this);
            }catch (Exception e){
                systemGateway.registerDEService("{{packageName}}.core.runtime.ISystemRuntime", this.getDataEntityId(), this);
            }
        }
    }

    @Override
    protected void onPrepare() {
        super.onPrepare();
        try {
{{#each entity.allPSDEActions as |deAction|}}
                <#if deAction.isEnableBackend() && !(deAction.getPSSysSFPlugin()??)>
                  {{#if (eq deAction.actionType 'USERCUSTOM')}}
            this.getDataEntityRuntime().registerDEActionPluginRuntime(ACTION_{{upperCase deAction.name}}, new IDEActionPluginRuntime() {
                @Override
                public Object execute(IDataEntityRuntimeContext iDataEntityRuntimeContext, IPSDEAction iPSDEAction, Object[] args, Object actionData) throws Throwable {
                    {{#if neq deAction.pSDEActionReturn.type  'VOID'}}
                    return ActionSessionManager.getCurrentSession().execute(new IAction() {
                        @Override
                        public Object execute(Object[] args) throws Throwable {
                            return on{{pascalCase deAction.codeName}}(({getDEActionInputType(deAction)}) args[0]);
                        }
                    }, args, ITransactionalUtil.PROPAGATION_REQUIRED);
                    {{else}}
                    return ActionSessionManager.getCurrentSession().execute(new IAction() {
                        @Override
                        public Object execute(Object[] args) throws Throwable {
                            on{{pascalCase deAction.codeName}}(({getDEActionInputType(deAction)}) args[0]);
                            return null;
                        }
                    }, args, ITransactionalUtil.PROPAGATION_REQUIRED);
                    {{/if}}
                }
            });
                  {{elseif deAction.isRenderBeforeAfter}}
            this.getDataEntityRuntime().registerDEActionPluginRuntime(ACTION_{{upperCase deAction.name}}, new IDEActionPluginRuntime() {
                @Override
                public Object execute(IDataEntityRuntimeContext iDataEntityRuntimeContext, IPSDEAction iPSDEAction, Object[] args, Object actionData) throws Throwable {
                    {getDEActionInputType2(deAction)} dto = ({getDEActionInputType2(deAction)}) args[0];
                    onBefore{deAction.getCodeName()}(dto);
                    <#if actionReturnType != 'VOID'>{getDEActionReturn(deAction)} result = ({getDEActionReturn(deAction)}) </#if>iDataEntityRuntimeContext.executeActionReal(iPSDEAction, args, actionData);
                    <#if actionReturnType != 'VOID'>
                    return onAfter{deAction.getCodeName()}(<#if actionReturnType != 'VOID'>result, </#if>dto);
                    <#else>
                    onAfter{deAction.getCodeName()}(<#if actionReturnType != 'VOID'> result, </#if>dto);
                    return null;
                    </#if>
                }
            });
                  </#if>
                  {{/if}}
{{/each}}

            //结果集
{{#each entity.allPSDEDataSets as |dataSet|}}
            this.getDataEntityRuntime().registerDEDataSetPluginRuntime(DATASET_{{upperCase dataSet.name}}, new IDEDataSetPluginRuntime() {
                @Override
                public Object fetch(IDataEntityRuntimeContext iDataEntityRuntimeContext, IPSDEDataSet iPSDEDataSet, Object[] args, Object actionData) throws Throwable {
                    return iDataEntityRuntimeContext.fetchDataSetReal(iPSDEDataSet, args, actionData);
                }
            });
{{/each}}
        } catch (Throwable e) {
            throw new RuntimeException(String.format("准备实体服务发生异常，%s", e.getMessage()), e);
        }
    }

{{#each entity.allPSDEActions as |deAction|}}
    {{#if (and deAction.enableBackend (unless deAction.pSSysSFPlugin))}}
        {{#if (eq deAction.actionType 'USERCUSTOM')}}
    protected {getDEActionReturn(deAction)} on{{pascalCase deAction.codeName}}({getDEActionInput(deAction)}) throws Throwable {
        throw new DataEntityRuntimeException(this.getDataEntityRuntime(), String.format("行为[%s]未实现", "{{#if deAction.logicName}}{{deAction.logicName}}{{else}}{{deAction.name}}{{/if}}"), Errors.NOTIMPL);
    }
          {{elseif deAction.isRenderBeforeAfter}}

    protected void onBefore{{pascalCase deAction.codeName}}({getDEActionInput2(deAction)}) throws Throwable {
        
     }

    protected {getDEActionReturn(deAction)} onAfter{{pascalCase deAction.codeName}}({{#if neq deAction.pSDEActionReturn.type 'VOID'}}{getDEActionReturn(deAction)} result, {{/if}}{getDEActionInput2(deAction)}) throws Throwable {
      {{#if neq deAction.pSDEActionReturn.type 'VOID'}}return result;{{/if}}
    }

        {{/if}}
    {{/if}}
{{/each}}
}