出差费用管理模块主要分为两个部分 支出和预付,一般公司称之为报销和请款,也就是出差之类费用的报销和出差前向公司预支一部分现金。AX的出差费用管理模块基本能满足一般公司的请款和报销需求。
一般业务上需要满足如下功能:
1.提供界面让用户可以输入请款和报销
2.提供审批功能
涉及到公司钱的问题,一般需要审批
3.请款和报销需要在总帐上有所体现,也就是生成相应的日记帐和凭证
4.请款和报销需要核销,正如预收和应收需要核销一样。
第1点和第2点介绍跟其他模块没啥大的区别,这里就不赘述了,唯一的区别可能就是出差费用管理模块的输入只能在EP上做。
对于第3点,与其它模块一样,生成的日记帐的借贷科目需要提前设好,不可能要求用户在录入单据的时候自己去选择费用科目,用户更习惯选择的是费用类别之类,至于对应哪个科目是财务要关心的事情,于是很自然借方的科目就有地方设置了,嗯,需要在费用类别那地方挂一个费用科目
AX的操作路径:
出差费用管理->设置->支出条目->支出类别

接下来就是贷方了,贷方也就是这个费用是谁来承担的,一般情况下我们员工报销应该是员工承担了这部分费用,所以一般贷记员工的应付就可以了。
AX费用管理模块如果要贷记员工,需要在员工窗体关联一个供应商帐户,每个员工对应一个供应商帐户,虽然不是很喜欢这种处理方式,因为相当于所有的员工要对应一个供应商帐户,怎么看怎么别扭,但是为了使用标准的应付模块来给员工付款,也想不到更好的实现方式,如果用财务维度做辅助核算,每个公司对维度的使用情况又不同,很难做到标准化,于是这种笨拙的方式也是无奈之举。
出差费用管理->设置->员工详细信息

当然除了贷记员工外,还可以由公司或者第三方供应商帮忙承担了费用,这样的话就需要贷记公司的银行账户或者第三方供应商账户,到底贷记员工还是公司或者第三方供应商,这个也应该有个地方定义。
操作路径:出差费用管理->设置->支出条目->付款方式

付款方式里 支出所有者 这个字段只是个描述字段不起决定作用,重要的是对方科目类型和对方科目。
员工:如果选择了员工,则对方科目不能选择,因为系统会直接贷记到在员工窗体设置的供应商。
分类帐:选择了分类帐,需要指定一个过账科目,这样就会贷记到一个固定的会计科目。
银行:如果是公司支付了费用,则指定一个银行科目,生成的凭证会直接贷方会记到指定的银行科目。
所以通常情况下,对方科目类型选择员工就可以了。
在支出类别处关联一个默认的付款方式,这样只要用户选择一个费用类别,要生成凭证的借方和贷方科目就都有了。
另外,在安装完EP后,默认的预付功能不能用,说找不到页面之类,这是因为安装程序没有正确创建预付和预付审批对应的子站点导致的,在AOT上重新部署一下就可以了。

在前面介绍的一篇文章中介绍了用代码启动SSIS包的方法,http://www.cnblogs.com/Farseer1215/archive/2010/11/08/1871464.html,其中第二种方法必须在安装了SSIS组件的服务器上运行.
如果这样处理的实用性不是很强,不可能在每一台客户机上都装一个SSIS组件,所以最好的办法是在安装了SSIS组件的服务器上安装一个服务,其他客户端调用即可,于是可以考虑用WCF写一个小程序来运行SSIS包,其他的客户端直接调用服务。
1.创建WCF服务
在VS2010中选择创建WCF服务库,这时VS会用WCF库的模板创建一个项目,配置文件,接口和类实现都已经创建好,唯一要做的是事情是实现自己的逻辑。
要想启动SSIS需要用到ManagedDTS这个类库,添加对Microsoft.SqlServer.ManagedDTS这个DLL 的引用。
在接口定义中定义相应的操作和数据契约,在类中实现这些接口,定义了如下两个方法:
public SSISPackageResult ExecSSISPackage(string _packageName)
{
SSISPackageResult result = new SSISPackageResult();
try
{
Application application = new Application();
Package package = application.LoadFromSqlServer(_packageName, ".", null, null,null);
result.Execresult = package.Execute();
if (result.Execresult == DTSExecResult.Failure || result.Execresult == DTSExecResult.Canceled)
result.ExecInfo = string.Format("SSIS包{0}运行失败,请查看包运行日志!",_packageName);
else
result.ExecInfo = string.Format("SSIS包{0}运行成功",_packageName);
}
catch (Exception ex)
{
result.Execresult = DTSExecResult.Failure;
result.ExecInfo = string.Format("SSIS包{0}运行失败,具体异常信息为:"+ex.Message.ToString());
}
return result;
}
public SSISPackageResult ExecSSISPackageWithParam(string _packageName, string _variableName, string _variableValue)
{
SSISPackageResult result = new SSISPackageResult();
try
{
Application application = new Application();
Package package = application.LoadFromSqlServer(_packageName, ".", null, null,null);
package.Variables[_variableName].Value = _variableValue;
result.Execresult = package.Execute();
if (result.Execresult == DTSExecResult.Failure || result.Execresult == DTSExecResult.Canceled)
result.ExecInfo = string.Format("SSIS包{0}运行失败,请查看包运行日志!",_packageName);
else
result.ExecInfo = string.Format("SSIS包{0}运行成功",_packageName);
}
catch (Exception ex)
{
result.Execresult = DTSExecResult.Failure;
result.ExecInfo = string.Format("SSIS包{0}运行失败,具体异常信息为:"+ex.Message.ToString());
}
return result;
}
2.创建承载WCF服务的Windows服务
WCF服务的宿主可以是IIS,Windows Services,Windows Form甚至控制台命令程序,考虑到并不是所有服务器都会安装IIS,SRS2008也不再依赖于IIS,Windows Form和控制台命令程序控制起来不方便,所以采用Windows Services做为WCF服务的宿主程序。
在解决方案中加入一个新的项目WS_SSIS,项目模板采用Windows服务,添加对项目WCF_SSIS和System.ServiceModel的引用,在OnStart方法中添加启动WCF服务的代码:
ServiceHost serviceHost = new ServiceHost(typeof(SSISService));
serviceHost.Open();
因为System.Configuration不支持库的配置文件为服务增加一个配置文件,把WCF服务的配置文件内容拷贝过来。
为了安装服务,增加如下类,需要添加对程序集System.Configuration.Install的引用:
[RunInstaller(true)]
public class SSISServicesInstaller:Installer
{
private ServiceProcessInstaller process;
private ServiceInstaller service;
public SSISServicesInstaller()
{
process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
service = new ServiceInstaller();
service.ServiceName = "SSIS Service";
service.Description = "该服务用来执行SSIS包完成相应的数据整合任务";
Installers.Add(process);
Installers.Add(service);
}
}
这样在用InstallUtil.exe安装服务时会自动添加相应的服务,在Win7或者Windows2008上安装服务时要注意使用管理员运行InstallUtil,否则会出错。
运行后会在服务中添加SSISService:

安装时让SSIS服务木运行在本地服务帐户下,可根据实际情况修改服务的运行帐户,让其可以正确访问SSIS,然后启动服务。
3.创建WCF客户端调用WCF服务完成操作
可以用多种方法来实现在AX中调用WCF服务,可以先用C#写个DLL,使用添加服务生成代理类,然后用代理类调用WCF服务,然后在AX中引用该DLL。AX2009也支持直接添加服务引用,自动生成代理类供调用WCF服务使用。
AOT->References->添加服务引用

填写正确的信息:
其中WSDL URL就是WCF向外提供服务的URL地址,具体的详细信息参见WCF的相关知识。
.NET 代码命名空间在AX生成的代理类的命名空间,这个可以按照自己的习惯随便取名。
点击确定:

这样正确生成了调用WCF服务需要的客户端程序。
4.调用服务
写一个类调用WCF服务
static server void main(Args _args)
{
InterOpPermission interop = new InterOpPermission(InteropKind::ClrInterop);
SSISClient.ISSISServiceClient ssisServiceClient;
SSISClient.SSISPackageResult packageResult;
str bb;
;
interop.assert();
ssisServiceClient = new SSISClient.ISSISServiceClient();
packageResult = ssisServiceClient.ExecSSISPackage("InventTable");
info(packageResult.get_ExecInfo());
CodeAccessPermission::revertAssert();
}
运行结果如下:
