具有代表性的财务报表--应收帐

首先发一下牢骚,公司效益不好,我们被老美抛弃, 成为了内地一家企业的被收购方,按理被收购方是应该被集团替换掉系统才对的.但由于收购方的系统完善程度还远不如我们. 这不,没办法,收购方的其中一个工厂(目标工厂)做的产品与我们类似.需要用我们的系统管理.唉.. 这样一来, 就有我们忙的了, 可是现在的我们就相当于是二娘养的,做好了是应该的,做不好挨骂的份就落到身上了...         进入正文

系统自己写的,我们对基础资料的导入和环境的部署自然不是问题了,但目标工厂提出了一个较为紧急的问题就是客户的对帐单,由于系统目前的应收款单不符合要求,需要额外的写一个,由于财务与信贷的报表一向由我负责. 老大自然把这任务安排到我的头上. 于是不得不梳理一下财务数据取数. 我觉得挺有代表性的.于是决定写下来. 包括帖出SQL的代码. 我相信大部分ERP系统都不外乎这几种情况. 顶多是数据源的TABLE不一样罢了. 先上效果图.

这里有几个需要注意的地方,水晶报表按组分页和统计. 还有页码重置等..

效果很简单.这里主要的是计算期初的数值和本期的回款.

以下是SQL代码,留意一下参数.

  
    
    
 /*            
developed history            
created by geton jew on 2014-6-19            
            
popurse: for credit report  rpt_woer_statement            
            
this sp invoked another store_procedure CAL_WOER_STATEMENT to calculate the opening data            
         
modified by geton on 2014-6-25        
decription: due to users want to show the open bal enevn no data during these period        
   use left join instead of inner join,          
        
modified by geton on 2014-6-27        
decription: added @soffice parameter as a filter       
RPT_WOER_STATEMENT '0840','0840','2014/7/3','2014/7/23','ALL'    
modified by geton on 2014-07-01    
decription: added CN/DN journal to this period     
*/              
CREATE   PROCEDURE [dbo].[RPT_WOER_STATEMENT]                
@cus1 char(4)='Z21N',   @cus2 char(4)='Z23N',             
@begdate char(10)='2014/04/2',                
@enddate char(10)='2014/06/26',        
@soffice varchar(10) = 'ALL'                
AS                
--                
           
CREATE TABLE #RESULT            
(            
 CUS CHAR(4),            
 TYPE VARCHAR(15),            
 BEGDATE CHAR(10),            
 ENDDATE CHAR(10),            
 AMT FLOAT,            
 OSAMT FLOAT,            
 ORIAMT FLOAT,            
 ORIOSAMT FLOAT            
)                
declare @where varchar(10)        
if @soffice='ALL'        
 set @where = '%'        
else        
 set @where = @soffice        
        
--select @where        
-- @BEGDATE 传进去要少一天             
DECLARE @cutday VARCHAR(10)          
SELECT  @cutday=CONVERT(VARCHAR(10),DATEADD(DAY,-1,CONVERT(SMALLDATETIME,@begdate)),121)           
INSERT INTO #RESULT            
EXEC CAL_WOER_STATEMENT @cus1,@cus2,@cutday,@enddate,@where            
          
       
SELECT A.*,B.TYPE AS RECTYPE,B.BEGDATE AS RECBEGDATE,B.ENDDATE AS RECENDDATE,          
 -isnull(B.AMT,0) AS RECAMT,          
 -isnull(B.OSAMT,0) AS RECOSAMT,          
 -isnull(B.ORIAMT,0) AS RECORIAMT,          
 -isnull(B.ORIOSAMT,0) AS RECORIOSAMT,          
  CUSNAME=SPACE(400),              
  CUSFAX=SPACE(20),              
  CUSTEL=SPACE(20),              
  CONTACT=SPACE(40)          
INTO #FINANAL FROM #RESULT A left JOIN #RESULT B          
ON A.CUS=B.CUS AND B.TYPE='*Received*'          
WHERE A.TYPE='*Openning*'          
        
          
       
          
CREATE TABLE #TMP      
(      
  SINV CHAR(10),             
  INVNO CHAR(20),      
  PONO CHAR(40),            
  SONUM CHAR(16),              
  MODEL CHAR(40),              
  CUSMODEL  CHAR(240),              
  OURPRO  CHAR(40),            
  PRODESC CHAR(250),              
  QTY float,             
  PRICE float,        
  SUMQTY float,          
  TAXQTY float,          
  SIDATE smalldatetime,              
  CUSNUM CHAR(4),      
  TAX float,       
  COMPANY CHAR(40),              
  COMPANY1 CHAR(40),              
  TEL CHAR(25),              
  FAX CHAR(25),              
  ADDR1 CHAR(500),                 
  CURR CHAR(5),               
  SUMALL FLOAT,             
  FUOM CHAR(5),       
  F2 BIT,              
  INVDATE smalldatetime,      
  COMMENT CHAR(200)         
)      
PRINT 'K'      
INSERT INTO #TMP(SINV,INVNO,PONO,SONUM,MODEL,CUSMODEL,OURPRO,QTY,PRICE,SUMQTY,TAXQTY,SIDATE,CUSNUM,TAX,CURR,FUOM,F2,INVDATE,COMMENT)           
SELECT               
  SINV.SINV,       
  CASE  WHEN ISNULL(SINV.INVNUM,'A')='A'  THEN SINV.DN  ELSE  SINV.INVNUM  END,        
  SO.YOURREF,             
  SO.SONUM,              
  SODTL.PRONUM,              
  SODTL2.COMMENT,              
  SINVDTL.MODEL,                  
  SINVDTL.QTY,                 
  PRICE,          
  PRICE*SINVDTL.QTY,          
  (SINVDTL.QTY*CASE WHEN SO.TAXINC='TRUE' THEN SODTL.UPRICE/(1+SO.TAX) END)*0.17,              
  SINV.IDATE,              
  SINV.CUS,                 
  SINV.TAX,                         
  SO.CURRENCY,                     
  SINVDTL.SUOM,      
  SO.F2,              
  CASE WHEN  ISNULL(SINV.INVDATE,'1900/01/01')='1900/01/01'THEN SINV.IDATE  ELSE SINV.INVDATE END,      
  SODTL2.COMMENT         
FROM               
  SINV WITH (NOLOCK),SINVDTL WITH (NOLOCK),SODTL WITH (NOLOCK),SO WITH (NOLOCK),SODTL2 WITH (NOLOCK),CUS WITH(NOLOCK)             
WHERE               
  SINV.SINV=SINVDTL.SINV AND              
  SINVDTL.SO=SODTL.SONUM AND              
  SINVDTL.MODEL=SODTL.OURPRO AND              
  SODTL.SONUM=SO.SONUM AND          
  SINV.CUS = CUS.CUS AND  CUS.OFFNUM LIKE @where and             
  CUS.CUS BETWEEN @cus1 AND  @cus2 AND            
  SINV.IDATE BETWEEN @begdate AND @enddate AND               
  SODTL2.SONUM=SODTL.SONUM AND               
  SODTL2.PRONUM=SODTL.PRONUM AND               
  SODTL2.LOT=SINVDTL.LOT             
     
     
 --  CN/DN单据      
INSERT #TMP (SINV,SIDATE,CUSNUM,SONUM,SUMQTY,COMMENT)      
SELECT SINV,IDATE,SINV.CUS,'DN',AMT,INVCOMMENT FROM SINV with (nolock), CUS with (nolock)      
WHERE SITYPE='a' and      
SINV.CUS = CUS.CUS AND CUS.OFFNUM LIKE @where and             
CUS.CUS BETWEEN @cus1 AND  @cus2 AND            
SINV.IDATE BETWEEN @begdate AND @enddate      
UNION       
SELECT SRNUM,SR.DATE,CUSNUM,'CN',-AMT,COMMENT FROM SR, CUS       
WHERE SRTYPE='a' and       
SR.CUSNUM = CUS.CUS AND  CUS.OFFNUM LIKE @where and             
CUS.CUS BETWEEN @cus1 AND  @cus2 AND            
SR.DATE BETWEEN @begdate AND @enddate        
      
            
UPDATE #TMP            
SET PRODESC=P.PRODESC FROM PRODUCT P WITH (NOLOCK)            
WHERE P.PRONUM=#TMP.OURPRO            
              
              
UPDATE   #TMP              
SET  COMPANY=COMPANYINFO.CONAME,ADDR1=COMPANYINFO.ADDR1,COMPANY1=COMPANYINFO.CONAME2,TEL=COMPANYINFO.TEL1,FAX=COMPANYINFO.FAX              
FROM COMPANYINFO WITH (NOLOCK)             
              
UPDATE   #TMP  SET  INVNO=JOU.XREF            
FROM   JOU,#TMP              
WHERE  #TMP.SINV=JOU.JOU AND #TMP.INVNO=''              
 
-- 采用全连接,不然表中始终会有记录不显示             
SELECT *  into #fdata FROM #FINANAL FULL join #TMP on #FINANAL.CUS=#TMP.CUSNUM          
ORDER BY SIDATE ASC      

--按客户代码更新相应的客户信息.          
UPDATE   #fdata  SET CUS=isnull(#fdata.CUS,#fdata.CUSNUM),ORIOSAMT=ISNULL(ORIOSAMT,0),RECORIOSAMT=ISNULL(RECORIOSAMT,0),  
CUSNAME=CUS.NAME,CUSFAX=CUS.FAX,CUSTEL=CUS.TEL1,CONTACT=CUS.CONTACT             
FROM   CUS WITH (NOLOCK)            
WHERE  isnull(#fdata.CUS,#fdata.CUSNUM)=CUS.CUS  
  
update #fdata set PRODESC=MODEL      
  
select * from   #fdata           
              
DROP TABLE #TMP, #RESULT,#FINANAL,#fdata     
    

剩下的另一个SP的代码.主要的计算逻辑都在这里.里面包含了描述.(20141027编辑此文章,脚本有所修改.)

        
          
/*          
Developed History          
Created by Geton Jew on 2014-6-19          
          
Popurse: For Credit Report  RPT_WOER_STATEMENT          
          
this was invoked by another store_procedure: RPT_WOER_STATEMENT to show  the final data           
          
-- RPT_WOER_STATEMENT '0820','0820','2014/7/4','2014/7/25','%'      
  
modified by geton on 2014-7-22,2014-7-28     
  
2014-10-24  Content: Change the Received money calculate method.  
          
*/           
          
-- select * from SINV WHERE CUS= '0820'        
          
             
alter   procedure [dbo].[CAL_WOER_STATEMENT]                
@cus1 char(4)='Z21N',   @cus2 char(4)='Z21N',             
@begdate char(10)='2014/06/25',                
@enddate char(10)='2014/06/26',          
@where varchar(10) = '%'                 
as                
--                
--grant execute on CAL_WOER_STATEMENT to public            
CREATE TABLE #result            
(            
 CUS char(4),            
 TYPE varchar(15),            
 BEGDATE char(10),            
 ENDDATE char(10),            
 AMT FLOAT,            
 OSAMT FLOAT,            
 ORIAMT FLOAT,            
 ORIOSAMT FLOAT            
)                
              
declare @delclose int                
set @delclose=1                 
             
-- 送货单                
select  SI.CUS,                 
 J.JOUTYPE,                 
 J.JOU,                 
 J.IDATE,                 
 AMT=JD.DR,                 
 REF=convert(varchar(30),J.JOU),                    
 OSAMT=JD.DR,              
 ORIAMT=JD.ORIAMT,                
 ORIOSAMT=JD.ORIAMT,                
 CURR=SI.CURR                     
into #T1 from  SINV SI with (nolock),JOU J with (nolock), JOUDTL JD with (nolock), CUS  with (nolock)              
where                
 SI.JOUTYPE=J.JOUTYPE and                 
 SI.SINV=J.JOU and                
 J.JOUTYPE=JD.JOUTYPE and                 
 J.JOU=JD.JOU and                 
 JD.ACC=SI.RECACC and                  
 SI.CUS  between @cus1 and @cus2 and               
 SI.CUS = CUS.CUS and CUS.OFFNUM LIKE @where and           
 SI.IDATE <= @enddate and                
 (JD.R = 'false'  or JD.RR=0) and isnull(SI.DN,'')<>'NIL'                
              
-- 收款  截止为参数2日期   -- select * from CUS WHERE CUS='Z21N'          
insert #T1                
 select AR.CUS,                
  'RV',                 
  AR.JOU,                   
  AR.IDATE,                
  AMT=-AR.AMT,  -- AMT为收款金额,这里为负数               
  AR.CHK,                  
  OSAMT=0,    -- OSAMT栏位为0               
  ORIAMT=-ORIAMT,   -- 收的是原幣金額             
  OSORIAMT=0,               
  CURR=AR.CURR             
 from AREC AR  with (nolock), CUS  with (nolock)            
  where   AR.CUS = CUS.CUS  and  --CUS.OFFNUM LIKE @where and            
  AR.CUS  between @cus1 and @cus2 and  CUS.OFFNUM LIKE @where and           
  AR.IDATE <= @enddate            
    
              
  -- [CAL_WOER_STATEMENT_zz] '0708','0708','2014/7/1','2014/7/28','%'                   
select  R2.JOU,R.CUS,MISCHRG=sum(R2.DR+R2.CR)    -- 手续费等            
into #ta1                
from ARECDTL2 R2  with (nolock), AREC R  with (nolock),CUS  with (nolock)            
where                 
 R.CUS=CUS.CUS and R.JOU=R2.JOU and R2.ACC<>R.AR and  -- 科目不等于该客户应收科目              
 R.CUS  between @cus1 and @cus2 and  CUS.OFFNUM LIKE @where and              
 R.IDATE <= @begdate              
group by                 
R2.JOU,R.CUS             
              
select  R2.JOU, R.CUS,DEPOSIT=sum(R2.DR-R2.CR),ODEPOSIT=sum(R2.ORIAMT)                
into #tb1                
from  ARECDTL2 R2  with (nolock),AREC R  with (nolock),CUS  with (nolock)              
where  R.CUS = CUS.CUS and R.JOU=R2.JOU and  R2.ACC=R.AR and    -- 科目等于该客户应收科目,即应收减少,相当于有余钱在我们公司            
R.CUS  between @cus1 and @cus2 and  CUS.OFFNUM LIKE @where and                
R.IDATE <= @begdate              
group by R2.JOU,R.CUS               
            
             
update #T1 set AMT=#T1.AMT-#ta1.MISCHRG    -- AMT收款增加,即等于对冲票据总额            
from #ta1               
where #T1.JOUTYPE='RV' and #T1.JOU=#ta1.JOU AND #ta1.CUS = #T1.CUS              
            
             
update #T1 set OSAMT=#tb1.DEPOSIT, ORIOSAMT=#tb1.ODEPOSIT  -- 这里更新为客户新的应收,分别为本位币和原币              
 from #tb1                
 where #T1.JOUTYPE='RV' and #T1.JOU=#tb1.JOU  AND #tb1.CUS = #T1.CUS                
              
/***                
退货                
***/                 
 --print 88              
insert #T1                
select  SR.CUSNUM,                
 JD.JOUTYPE,                 
 SR.SRNUM,                 
 SR.DATE,                     
 AMT=-JD.CR,  -- 负数,退钱               
 isnull(SR.XREF,''),                    
 OSAMT=-JD.CR,  -- 负数,退钱                
 ORIAMT=JD.ORIAMT,   -- 同样,这里会负数             
 ORIOSAMT=JD.ORIAMT, -- 同样,这里会负数               
 CURR=SR.CURR                  
from  SR,JOUDTL JD,CUS              
where SR.RECACC=JD.ACC and SR.JOUTYPE=JD.JOUTYPE and SR.SRNUM=JD.JOU and                
 SR.CUSNUM  between @cus1 and @cus2 and  CUS.OFFNUM LIKE @where and                 
 SR.DATE <= @enddate and                
 (JD.R = 'false'  or JD.RR=0) and isnull(SR.XREF,'')<>'NIL' and SR.CUSNUM=CUS.CUS              
              
/***                
update OSAMT                
***/                
select  SINV,#T1.CUS, AMTPAID=sum(AMTPAID),ORIAMTPAID=sum(ARECDTL.ORIAMT)       --  AMTPAID 應收金額,ORIAMT原幣金額                
into  #T3                 
from AREC, ARECDTL,  #T1                
where                 
 ARECDTL.SINV=#T1.JOU and AREC.JOU=ARECDTL.JOU and #T1.CUS=AREC.CUS and               
 AREC.IDATE <= @begdate     -- 这里的CUTDATE被我换了@begdate            
group by                 
SINV,#T1.CUS             
               
update #T1 set OSAMT=OSAMT-AMTPAID, ORIOSAMT=ORIOSAMT-ORIAMTPAID                 
from #T3 where                
#T3.SINV=#T1.JOU  AND #T3.CUS=#T1.CUS              
            
-- select * from #T1 WHERE JOU='NSB4001333'            
-- 这段时间收款分开计算            
            
select  R2.JOU,R.CUS,MISCHRG=sum(R2.DR+R2.CR)    -- 手续费等            
into #ta2                
from ARECDTL2 R2  with (nolock), AREC R  with (nolock),CUS  with (nolock)            
where                 
 R.CUS=CUS.CUS and R.JOU=R2.JOU and R2.ACC<>R.AR and  -- 科目不等于该客户 应收科目              
 R.CUS  between @cus1 and @cus2 and  CUS.OFFNUM LIKE @where and              
 R.IDATE >@begdate  and  R.IDATE <= @enddate            
group by                 
R2.JOU,R.CUS             
              
select  R2.JOU, R.CUS,DEPOSIT=sum(R2.DR-R2.CR),ODEPOSIT=sum(R2.ORIAMT)                
into #tb2                
from  ARECDTL2 R2  with (nolock),AREC R  with (nolock),CUS  with (nolock)              
where  R.CUS = CUS.CUS and R.JOU=R2.JOU and  R2.ACC=R.AR and    -- 科目等于该客户应收科目,即冲掉一笔应收,又开一笔应收,相当于调到期的应收            
R.CUS  between @cus1 and @cus2 and  CUS.OFFNUM LIKE @where and                
 R.IDATE >@begdate  and  R.IDATE <= @enddate            
group by R2.JOU,R.CUS              
            
update #T1 set AMT=#T1.AMT-#ta2.MISCHRG    -- AMT收款增加,即等于对冲票据总额            
from #ta2               
where #T1.JOUTYPE='RV' and #T1.JOU=#ta2.JOU AND #ta2.CUS = #T1.CUS              
            
             
update #T1 set OSAMT=#tb2.DEPOSIT, ORIOSAMT=#tb2.ODEPOSIT  -- 这里更新为客户余的钱在我们公司,分别为本位币和原币              
 from #tb2             
 where #T1.JOUTYPE='RV' and #T1.JOU=#tb2.JOU  AND #tb2.CUS = #T1.CUS    
              
-- modified flag 20141024            
-- select  SINV,#T1.CUS,                 
-- AMTPAID=sum(isnull(AMTPAID,AREC.AMT)), -- 假如没有冲帐,即有预收款等,就直接取一层的金额了。                
-- ORIAMTPAID=sum(isnull(ARECDTL.ORIAMT,AREC.ORIAMT))                     
--into  #T4                 
--from  #T1                 
--left join AREC with (nolock) on  #T1.JOU=AREC.JOU and   #T1.CUS=AREC.CUS and  AREC.CHKACC IN('36000','AAAA')  --如果算收款的是特定科目,则这里应该加设科目,否则一些调帐的收票或其它收票将会做会收款。               
--left join ARECDTL on AREC.JOU=ARECDTL.JOU    
--where  AREC.IDATE>@begdate  and AREC.IDATE <= @enddate            
--group by SINV ,#T1.CUS    
  
  
-- modified flag: 由20141024的假如没有冲帐,即有预收款等,就直接取一层的金额了。  
-- 直接换取收票金额,而不管它有没有冲销, 同时加上手续费(科目是6601)  
 select  #T1.JOU,#T1.CUS,                 
 AMTPAID=sum(isnull(AREC.AMT,0)+ isnull(ARECDTL2.ORIAMT*ARECDTL2.RATE,0)),   
 ORIAMTPAID=sum(isnull(AREC.ORIAMT,0) + isnull(ARECDTL2.ORIAMT,0))                     
into  #T4                 
from  #T1                 
left join AREC with (nolock) on  #T1.JOU=AREC.JOU and    
 #T1.CUS=AREC.CUS and  AREC.CHKACC IN('36000','AAAA')  --如果算收款的是特定科目,则这里应该加设科目,否则一些调帐的收票或其它收票将会做会收款。               
left join ARECDTL2 on AREC.JOU=ARECDTL2.JOU AND ARECDTL2.ACC='6601'    
where  AREC.IDATE>@begdate  and AREC.IDATE <= @enddate            
group by #T1.JOU ,#T1.CUS    
  
                  
         
 -- [CAL_WOER_STATEMENT_zz] '0708','0708','2014/7/1','2014/7/28','%'              
select CUS, AMTPAID=sum(AMTPAID),ORIAMTPAID=sum(#T4.ORIAMTPAID)                     
into  #T5               
FROM #T4 GROUP BY CUS              
          
            
/***                
group all entry before sid1 to form one entries and delete                
the individual ones                
***/                
if @delclose=1                
delete #T1 where OSAMT=0                
              
--select * from #T1 where IDATE < @begdate order by IDATE ASC            
              
select  CUS,                 
 AMT=sum(AMT),                 
 OSAMT=sum(OSAMT),                 
 ORIAMT=sum(ORIAMT),                 
 ORIOSAMT=sum(ORIOSAMT)                 
into #T2 from  #T1              
where                
 IDATE <= @begdate                 
group by                 
 CUS              
              
--delete #T1 where IDATE < @begdate                
insert #result                 
select  CUS,            
 '*Openning*',            
 convert(varchar(10),convert(smalldatetime,'1900/01/01'),121),                
 convert(varchar(10),convert(smalldatetime,@begdate),121),                     
 AMT,                  
 OSAMT,                  
 ORIAMT,                 
 ORIOSAMT          
from #T2                
  
  
--WHERE ORIOSAMT>0                
                
/***                
以上算完了期初,所以收票还要加上这个期间的数            
***/                
insert #result                 
select  CUS,                     
 '*Received*',                 
 convert(varchar(10),dateadd(day,1,convert(smalldatetime,@begdate)),121),            
 convert(varchar(10),convert(smalldatetime,@enddate),121),                   
 -AMTPAID,                        
 -ORIAMTPAID,              
 -AMTPAID,                 
 -ORIAMTPAID            
from #T5                

-- 如果只有期初,没有回款,那么添加回款为0.  
insert #result    
select CUS,                     
 '*Received*',                 
 convert(varchar(10),dateadd(day,1,convert(smalldatetime,@begdate)),121),            
 convert(varchar(10),convert(smalldatetime,@enddate),121),0,0,0,0    
FROM CUS with (nolock) WHERE CUS  between @cus1 and @cus2 and  CUS.OFFNUM LIKE @where   
and CUS NOT IN (select CUS FROM #result WHERE TYPE='*Received*')      
--select * from #result  
    
--  如果只有本期回款却没有期初的话,要插入期初为0,以便后续报表显示    
-- [CAL_WOER_STATEMENT] '0716','0716','2014/7/1','2014/7/28','%'        
insert  #result --(CUS,TYPE,BEGDATE,ENDDATE)    
SELECT CUS,'*Openning*',convert(varchar(10),convert(smalldatetime,'1900/01/01'),121), convert(varchar(10),convert(smalldatetime,@begdate),121),0,0,0,0    
FROM #result  a     
WHERE TYPE='*Received*' AND NOT EXISTS ( SELECT * FROM #result  b where a.CUS = b.CUS and b.TYPE='*Openning*')    
    
    
             
            
select * from #result order by CUS ASC,BEGDATE ASC             
drop table #ta1,#tb1, #ta2,#tb2,#T1,#T2,#T3,#T4,#T5,#result            
原文地址:https://www.cnblogs.com/Geton/p/3812433.html