“逆向思维”求证公交电子车票售票收入的真实性
闫晓军(山东省济南市审计局)
【发布时间:2014年05月28日】
字号:【大】 【中】 【小】
    
    现如今,依托信息化网络平台,集电子车票充值和刷卡消费于一体的公交电子车票系统得到了广泛应用。这在给市民出行带来了极大便捷的同时,也在改变着公交公司内部运营管理模式。电子车票充值收入的核定在信息化条件下显得尤为简单,无非是对充值纪录进行加总,但如何验证电子车票售票收入的真实性和完整性,从而进一步验证该信息系统的安全性和可靠性?这是摆在审计人员面前的一道难题。
    
    电子车票实行预付费方式,即充值在前,刷卡消费在后。围绕这种运营模式,审计人员通过“逆向思维”,从刷卡消费入手倒推电子车票售票收入,即:电子车票能正常使用,有刷卡消费记录,则表明该电子车票此前应当有相应的充值记录。
    
    目前,公交在用的电子车票大致分为2类,一类是“月票型”,消费方式为包月付费。“月票型”电子车票单月费用固定,从刷卡消费记录中查询出某月有多少张在用的“月票型”电子车票,乘上单月费用,即可求得此种类型电子车票的售票收入。另一类电子车票,即“普通型”,它的消费方式为按次付费,每使用一次,则从该电子车票余额中扣除此次乘车费用。因此,在刷卡消费记录中,某张电子车票的余额以时间先后为序逐渐递减,呈现出一条规律变化的“曲线”。若在某时间点余额较上一次不降反增,即在“曲线”上出现“拐点”,则可确认该电子车票在“拐点”前后两次刷卡时间点之间有充值情况发生。电子车票预售(充值)金额即为“拐点”前后余额之差。
    
    根据上述思路,可计算出某月电子车票售票收入,与财务实际结算数据进行比较,即可验证这部分收入的真实性和完整性。从而为进一步查证该系统的安全性和可靠性提供相关证据和线索。
    
    这里以“普通型”电子车票为例,介绍一下该思路在现场审计实施系统(AO)中的具体实现方法。首先介绍一下公交公司信息系统相关数据表结构:
    
    刷卡消费记录表主要包括以下内容:电子车票卡类型,电子车票卡编号,刷卡日期,刷卡时间,电子车票卡余额,本此刷卡消费金额等。
    
    预售(充值)数据表主要包括:电子车票卡类型,电子车票卡编号,充值日期,充值金额,充值后余额等。
    
    第一步,整理刷卡消费记录表,理出消费“曲线”。从刷卡消费记录表中查询“普通卡”,并按卡号、刷卡日期升序、刷卡时间升序排序生成新表:过程表_普通卡刷卡次序,通过此步骤得到每张普通型电子车票以时间先后为序的刷卡消费流水记录。
    select 电子车票卡编号,刷卡日期,刷卡时间,电子车票卡余额,本此刷卡消费金额
    into 过程表_普通卡刷卡次序
    from 消费数据表
    where 电子车票卡类型 like '%普通卡%'
    order by 电子车票卡编号,刷卡日期 asc,刷卡时间 asc,电子车票卡余额 desc
    
    第二步,创建临时表,用于存放下一步查询结果。(创建的临时表名为:结果表_普通卡应有充值情况)。
    Var SqlStr;
    Begin
    //Sql语句赋值给变量
      SqlStr:='select ''普通卡'' as 电子车票卡类型,电子车票卡编号,刷卡日期 as 前一次刷卡时间,刷卡日期 as 后一次刷卡时间,电子车票卡余额 as 前一次刷卡后余额,电子车票卡余额 as 后一次刷卡后余额,本此刷卡消费金额 as 前一次刷卡消费金额,本此刷卡消费金额 as 后一次刷卡消费金额 from 过程表_普通卡刷卡次序 where 电子车票卡编号 like ''不存在''';
    //查询条件设置成where 电子车票卡编号 like '不存在',是为了在下一步时生产空表。
    //生成"结果表_普通卡应有充值情况"临时表
      CreateTempTable('结果表_普通卡应有充值情况',SqlStr);
    End.
    
    第三步,利用ASL审计脚本语言程序筛查“拐点”。根据“普通型”电子车票刷卡余额变化曲线,查找应用充值情况发生的普通卡,并将查询结果存放到“结果表_普通卡应有充值情况”中。
    var cx,bz,kh1,kh2,ye1,ye2,sktime1,sktime2,skje1,skje2,shu,sqlstr;
    //定义“处理”过程,将不同的数据类型转换成字符型。
    procedure chuli;
    begin
        shu:=length(kh1);
        kh1:=leftstr(kh1,shu);
        shu:=length(ye1);
        ye1:=leftstr(ye1,shu);
        shu:=length(sktime1);   
        sktime1:=leftstr(sktime1,shu);
        shu:=length(skje1);
        skje1:=leftstr(skje1,shu);
        shu:=length(kh2);
        kh2:=leftstr(kh2,shu);
        shu:=length(ye2);
        ye2:=leftstr(ye2,shu);
        shu:=length(sktime2);
        sktime2:=leftstr(sktime2,shu);
        shu:=length(skje2);
        skje2:=leftstr(skje2,shu);
    end;
    begin
        cx:=CreateQ('SELECT * FROM 过程表_普通卡刷卡次序', -1);
        bz:=Qeof(cx);   
        if bz<>1 then
          begin
              kh1:=QFDValue(cx,'电子车票卡编号');
              ye1:=QFDValue(cx,'电子车票卡余额');
              sktime1:=QFDValue(cx,'刷卡日期');
              skje1:=QFDValue(cx,'本此刷卡消费金额');
              while bz<>1 do
                  begin          
                      bz:=Qmov(cx,1);
                      bz:=Qeof(cx);
                      if bz<>1 then
                          begin
                              kh2:=QFDValue(cx,'电子车票卡编号');
                              ye2:=QFDValue(cx,'电子车票卡余额');
                              sktime2:=QFDValue(cx,'刷卡日期');
                              skje2:=QFDValue(cx,'本此刷卡消费金额');
                              if kh2=kh1 then
                                  begin
                                      if ye1
                                          begin
                                              call chuli;                                         
                                              sqlstr:='insert into 结果表_普通卡应有充值情况 (电子车票卡类型,电子车票卡编号,前一次刷卡时间,后一次刷卡时间,前一次刷卡后余额,后一次刷卡后余额,前一次刷卡消费金额,后一次刷卡消费金额) values (''普通卡'','+kh1+','+sktime1+','+sktime2+','+ye1+','+ye2+','+skje1+','+skje2+')';
                                              ExecuteUpdate(sqlstr);
                                          end;
                                  end;
                              kh1:=kh2;
                              ye1:=ye2;
                              sktime1:=sktime2;
                              skje1:=skje2;
                          end;
                  end;
          end;   
    end.
    
    第四步,结果比对生成疑点。分析检查普通型电子车票实际缴费与应有充值记录数据的一致性,并重点将审查月份应有充值记录但无实际缴费的电子车票情况生成表:疑点表_普通型电子车票应有充值但实际无充值记录情况。
    //定义变量
    Var SqlStr;
    Begin
    //Sql语句赋值给变量
    SqlStr:='select 左表.电子车票卡编号,(左表.后一次刷卡后余额+左表.后一次刷卡消费金额-左表.前一次刷卡后余额) as 本月应充值金额 from 结果表_普通卡应有充值情况 左表 left join 有缴费记录的电子车票数据表 右表 on 左表.电子车票卡编号=右表.电子车票卡编号 and 左表.电子车票卡类型=右表.电子车票卡类型 where 右表.电子车票卡编号 is null';
    //生成"疑点表_普通型电子车票应有充值但实际无充值记录情况"临时表
      CreateTempTable('疑点表_普通型电子车票应有充值但实际无充值记录情况',SqlStr);
    End.
    
    根据疑点表结果方可验证电子车票售票收入的真实和完整,还可进一步延伸调查。一方面,从数据库系统数据安全性、完整性上检查数据记录是否有遗漏,并查明遗漏的原因;另一方面,从业务数据产生的操作流程入手,检查售票业务的内控制度,排除人为因素造成的票款流失(未入账)。根据上述验证方法,即“数据间钩稽关系测试”,结合延伸调查结果,对公交信息系统的安全性、完整性以及有效性进行评价。(闫晓军)
【关闭】    【打印】