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

import java.io.Serializable;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.HashMap;
import java.util.Collection;
import java.math.BigInteger;
import java.math.BigDecimal;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.ObjectUtils;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cache.annotation.CacheEvict;
import com.baomidou.dynamic.datasource.annotation.DS;
import net.ibizsys.central.util.ISearchContextDTO;
import net.ibizsys.model.dataentity.action.IPSDEAction;
import net.ibizsys.model.dataentity.ds.IPSDEDataSet;
import net.ibizsys.central.plugin.boot.core.service.IBaseService;
import net.ibizsys.central.plugin.boot.core.helper.CachedBeanCopier;
import net.ibizsys.central.plugin.boot.core.helper.SpringContextHolder;
import net.ibizsys.central.dataentity.IDataEntityRuntimeContext;
import {{packageName}}.{{entity.module}}.domain.{{entity.codeName}};
import {{packageName}}.{{entity.module}}.filter.{{entity.codeName}}SearchContext;
{{#entity.relEntities}}
import {{packageName}}.{{module}}.domain.{{codeName}};
{{#neq storage "NONE"}}
import {{packageName}}.{{module}}.service.{{codeName}}Service;
{{/neq}}
{{/entity.relEntities}}

{{#dsName}}
@DS("{{entity.dataSource}}")
{{/dsName}}
public interface {{entity.codeName}}Service extends IBaseService<{{entity.codeName}}, {{entity.codeName}}SearchContext> {

    @Override
    default String getDataEntityId() {
        return "PSMODULES/{{entity.psSystemModule.codeName}}/PSDATAENTITIES/{{entity.codeName}}.json";
    }

    default {{entity.codeName}}Service getProxyService() {
        return SpringContextHolder.getBean(this.getClass());
    }

    default boolean create({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.create(dto);
    }
    default boolean onCreate({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.onCreate(dto);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean update({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.update(dto);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean onUpdate({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.onUpdate(dto);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean remove({{entity.keyField.type.java}} key) throws Throwable {
        return IBaseService.super.remove(key);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean onRemove({{entity.keyField.type.java}} key) throws Throwable {
        return IBaseService.super.onRemove(key);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean remove(List keys) throws Throwable {
        return IBaseService.super.remove(keys);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean onRemove(List keys) throws Throwable {
        return IBaseService.super.onRemove(keys);
    }

    default {{entity.codeName}} get({{entity.keyField.type.java}} key) throws Throwable {
        return IBaseService.super.get(key);
    }

    default {{entity.codeName}} onGet({{entity.keyField.type.java}} key) throws Throwable {
        return IBaseService.super.onGet(key);
    }

    default {{entity.codeName}} getDraft({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.getDraft(dto);
    }

    default {{entity.codeName}} onGetDraft({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.onGetDraft(dto);
    }

    default Integer checkKey({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.checkKey(dto);
    }

    default Integer onCheckKey({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.onCheckKey(dto);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean save({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.save(dto);
    }

    {{#entity.enableEntityCache}}
    @CacheEvict(value = "{{lowerCase entity.codeName}}", allEntries = true)
    {{/entity.enableEntityCache}}
    default boolean onSave({{entity.codeName}} dto) throws Throwable {
        return IBaseService.super.onSave(dto);
    }

    {{#each entity.extActions}}
    default {{outParam}} {{camelCase codeName}}({{inParam}} {{inParamName}})  throws Throwable {
        {{#if voidReturn}}
        IBaseService.super.callAction("{{codeName}}",{{inParamName}});
        return {{inParamName}};
        {{else}}
        IBaseService.super.beforeAction("{{codeName}}",{{inParamName}});
        {{outParam}} rt = ({{outParam}})IBaseService.super.forwardAction("{{codeName}}",{{inParamName}});
        if(rt!=null)
            IBaseService.super.afterAction("{{codeName}}",rt);
        return rt;
        {{/if}}
    }

    default {{outParam}} on{{pascalCase codeName}}({{inParam}} {{inParamName}})  throws Throwable {
        {{#if voidReturn}}
        IBaseService.super.onRealAction("{{codeName}}",{{inParamName}});
        return {{inParamName}};
        {{else}}
        return ({{outParam}})IBaseService.super.onRealAction("{{codeName}}",{{inParamName}});
        {{/if}}
    }

    {{/if}}

    {{/each}}

    {{#entity.dataSets}}
    default Page<{{entity.codeName}}> fetch{{pascalCase codeName}}({{entity.codeName}}SearchContext dto) throws Throwable {
        IBaseService.super.beforeFetch("{{codeName}}",dto);
        return (Page) IBaseService.super.forwardFetch("{{name}}",dto);
    }

    default Page<{{entity.codeName}}> onFetch{{pascalCase codeName}}({{entity.codeName}}SearchContext dto) throws Throwable {
        return (Page) IBaseService.super.onRealFetch("{{name}}",dto);
    }

    {{/entity.dataSets}}

}