⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sale.bak

📁 用keil开发的.单片机税控器程序.单片机用的是AT公司的.upsd3245
💻 BAK
📖 第 1 页 / 共 4 页
字号:

void InvoNoInc(ulong no,uchar mode)
{
	gyt4 fp,tp;
	uchar num,str[4],i,flg;
	uint adr;

	I2cRead(InvoiceNo,4,fp.str);	//当前发票号
	if(mode==1)no+=1;	//正常发票和退票处理
	else
	{//废票处理
		if(fp.dat!=no)	return;
		else no+=1;
	}
	I2cRead(UntreadNum,1,str);
	num=str[0];
	if(num!=0)
	{//有废票
		while(1)
		{
			flg=0;
			for(i=0;i<num;i++)
			{
				adr = i*4 + UntreadAdr;
				I2cRead(adr,4,tp.str);
				if(no==tp.dat)
				{
					no+=1;
					flg=1;
					break;
				}
			}
			if(flg==0)break;
		}
	}
	fp.dat=no;
	I2cWrite(InvoiceNo,4,fp.str);
}

void GetInvoNo()
{
	gyt4 fp;

	I2cRead(InvoiceNo,4,fp.str);
	CurInvoNo=fp.dat;	//本卷发票当前发票号
}

void GetFiscalCode(uchar *fcode)
{
	uchar i,str[50];
	gyt4 *fp,*xp;

	GetInvoNo();					//退票也必须用新的发票打印,所以也要找当前发票号
	memset(str,0,sizeof(str));
	ReadDate();
	xp=&InvoDate[0];
	fp=&str[0];
	fp->dat=xp->dat;
	str[4]=InvoiceFlg;
	fp=&str[5];
	fp->dat=CurInvoNo;				//退票也必须用新的发票打印
	for(i=0;i<30;i++)
		str[i+9]=WareClassStat[i];
	fp=&str[39];
	fp->dat=WareTotalPrice;

	IssueInvoice(str);		//获得税控码

	for(i=0;i<8;i++)fcode[i]=str[i];
}

void PayUnitInput(uchar *str)
{
	uchar i,dat[8];

	WindowsSet(4);
	strcpy(&WinHint[0][1],"请输入付款单位(个人):");
	strcpy(&WinHint[1][1],"=>");
	strcpy(&WinHint[2][1],"<名称长度最多10个汉字>");
	strcpy(&WinHint[3][1],"<允许输入英文字母>");
	WinDat[1][0]=3;WinDat[1][1]=20;
	dat[0]=K_TC;
	dat[1]=K_HJ;
	dat[2]=0;
	i=Windows(2,1,dat);
	strcpy(str,&WinDat[1][2]);
}

void PrintInvoice(uchar *fcode)
{
	uchar m,i;
	uchar str[51],warenamestr[18];
	ulong adr,no,warenum,price;
	gyt2 *tp;
	gyt4 *xp;

	OpenBox();
	//-----------------------------------------------------
	//打印发票
	memset(str,0,sizeof(str));
	I2cRead(InvoiceCode,10,str);
	PrintCodeNum("发票代码:",1,str,10);			//打印发票代码

	PaperControl(1,16);				//进纸一个汉字行,跳过已经印刷在发票上的发票号

	PrintStrNum("发票号:",CurInvoNo,0);		//打印当前发票号

	I2cRead(MachineNo,8,str);
	str[8]=0;
	PrintCodeNum("机器编号:",1,str,8);

	memset(str,0,sizeof(str));
	strcpy(str,"收款单位:");
	I2cRead(TaxpayerName,40,&str[9]);	
	PrintStr(str);

	memset(str,0,sizeof(str));
	strcpy(str,"税号:");
	I2cRead(TaxNumber,20,&str[5]);
	PrintStr(str);

	PrintTimeNo(SalerNo);			//打印开票日期和收款员编号
	memset(str,0,sizeof(str));
	if(InvoiceFlg==2)
	{//如果是退票,就打印所退的发票号
		strcpy(str,"原发票号:");
		NumToStr(UntreadCode.dat,&str[9],0);
		PrintStr(str);
	}
	else
	{
		strcpy(str,"付款单位(个人):");
		PayUnitInput(&str[15]);
		PrintStr(str);
	}

	PrintStr("项目             单价     数量    金额");
	//.....................................................
	//打印销售明细
	for(i=0;i<WareClass;i++)
	{
		tp = &WareList[i][0];
		no = tp->dat;
		if((no & 0xFF00) == 0xFF00)
		{
			no -= 0xFF00;
			adr = (no-1)*33 + ItemAdr;		//项目、部类
		}
		else
		{
			adr = (no-1)*39 + WareAdr;		//PLU
		}
		memset(warenamestr,0,sizeof(warenamestr));
		SerialFlashRead(FlashDat,adr,16,warenamestr);
		xp=&WareList[i][2];			//价格
		price = xp->dat;
		xp = &WareList[i][6];		//数量
		warenum = xp->dat;
		PrintItem(warenamestr,price,warenum);
	}
	//.....................................................
	memset(str,0,sizeof(str));
//	strcpy(str,"金额小计:    ");
//	NumToStr((WareTotalPrice+Discount-Surcharge),&str[14],1);
//	PrintStr(str);					//允许整体加费、打折时打印
//	memset(str,0,sizeof(str));
//	if(Surcharge!=0)
//	{
//		strcpy(str,"整体加费:  ");
//		NumToStr(Surcharge,&str[11],1);
//		PrintStr(str);
//		memset(str,0,sizeof(str));
//	}
//	if(Discount!=0)
//	{
//		strcpy(str,"整体打折:  ");
//		NumToStr(Discount,&str[11],1);
//		PrintStr(str);
//		memset(str,0,sizeof(str));
//	}

	if(InvoiceFlg==1)
	{
		strcpy(str,"合计(大写):  ");
		PrintStrNum("合计(小写):  ",WareTotalPrice,1);
		m=13;
	}
	else
	{
		if(InvoiceFlg==2)
		{
			strcpy(str,"合计(大写):退  ");
			PrintStrNum("合计(小写):--  ",WareTotalPrice,1);
			m=15;
		}
	}
	NumToCash(WareTotalPrice,&str[m]);
	PrintStr(str);
	PrintCodeNum("税控码:",0,fcode,8);
	I2cRead(BlackFlg,1,str);
	if(str[0]==1)
		BlackOrientation();
	else
		PaperControl(1,48);		//进纸3个汉字行
//	PrintHome();		//打印头回位
	VfdClear();
}

void ProhibitSaleHint()
{
	LcdDisplay(16,0,"日交易存储器已满,",3);
	Hint(32,0,"禁止继续销售!",0);
}

void PowerDetect(uchar x,gyt2 num,uchar *str)
{//掉电保护	
	if(PwrFlg!=0)
	{
		if(x)
		{
			I2cWrite(IntradayTime,64,str);
			I2cWrite(DailyDatNum,2,num.str);//更新日交易数量
		}
		while(1);
	}
}

uchar DailySign()
{//处理日交易签名,但是不清空日交易缓冲区
	uchar i,str[70],dat[130];
	gyt4 *fp;
	gyt2 wp;
	ulong adr,curtime,tp;

	I2cRead(DailyDatNum,2,wp.str);
	tp=wp.dat;
	if(tp>=DailyTradeMax)
	{//日交易存储器写满后禁止继续销售和日交易签名,开发票前也必须检测
		ProhibitSaleHint();
		return 0;
	}
	else
		adr=tp*192+DailyTradeDat;

	I2cRead(IntradayTime,64,str);			//从24C64读出临时日交易数据

	RxdBuf[0]=0xEF;
	RxdBuf[1]=0x03;
	SelectFile(0x00,0x00,0x02,RxdBuf,0);
	PowerDetect(0,wp,str);
	
	DailyCollectSign(0,str,dat);
	SerialFlashWrite(FlashDat,adr,64,str);	//写入日交易记录
	SerialFlashWrite(FlashDat,adr+64,128,dat);
	wp.dat++;								//日交易数量累加
	I2cWrite(DailyDatNum,2,wp.str);
	fp=&InvoDate[0];						//调用本函数前已经读出当前日期
	curtime=fp->dat;
	fp=&str[0];								//临时日交易数据日期
	tp = CalculateTime(fp->dat,1);
	if(curtime > tp)
	{//有间隔时间
		LcdDisplay(16,0,"正在处理日交易数据,",3);
		LcdDisplay(32,0,"请稍候......",0);
		fp->dat = tp;
		for(i=4;i<10;i++)str[i]=0;			//清零除时间和税种税目索引号以外的所有数据
		for(i=16;i<64;i++)str[i]=0;
		PowerDetect(1,wp,str);
		while(1)
		{
			if(wp.dat>=DailyTradeMax)
			{//日交易存储器写满后禁止继续销售和日交易签名,开发票前也必须检测
				ProhibitSaleHint();
				return 0;
			}
			else	adr+=192;
			DailyCollectSign(0,str,dat);
			SerialFlashWrite(FlashDat,adr,64,str);	//写入日交易记录
			SerialFlashWrite(FlashDat,adr+64,128,dat);
			wp.dat++;								//日交易数量累加
			I2cWrite(DailyDatNum,2,wp.str);			//避免中途出错后数据丢失
			tp = CalculateTime(fp->dat,1);
			if(tp >= curtime)break;
			fp->dat = tp;
			PowerDetect(1,wp,str);			
		}
	}
	return 1;
}

void DeclareAddUp()
{//累加申报数据,清空日交易缓冲区
	gyt4 *xp,*fp;
	gyt2 *kp,*mp;
	uchar i,str[66],tp[66];

	I2cRead(IntradayTime,64,tp);
	I2cRead(DecInvoNum1,62,str);
	xp=&str[0];kp=&tp[4];
	xp->dat += kp->dat;				//累加正常发票份数

	mp=&str[4];kp=&tp[6];
	mp->dat += kp->dat;				//累加退票份数

	mp=&str[6];kp=&tp[8];
	mp->dat += kp->dat;				//累加废票份数

	for(i=0;i<6;i++)
	{
		xp=&str[i*4+14];
		fp=&tp[i*4+16];
		xp->dat += fp->dat;			//累加正常发票分类累计金额
	}

	for(i=0;i<6;i++)
	{
		xp=&str[i*4+38];
		fp=&tp[i*4+40];
		xp->dat += fp->dat;			//累加退票分类累计金额
	}
	I2cWrite(DecInvoNum1,62,str);

	fp=&InvoDate[0];				//调用本函数前已经读出时间
	xp=&tp[0];
	xp->dat=fp->dat;				//更新日期
	for(i=4;i<10;i++)tp[i]=0;		//日期已经更新,税种税目索引号不清零
	for(i=16;i<64;i++)tp[i]=0;
	I2cWrite(IntradayTime,64,tp);
}

uchar AutoDailySign()
{
	uchar i;
	gyt4 *xp,wp;
	
	if(!FiscalIdentify(1))return 0;
	ReadDate();
	xp=&InvoDate[0];
	I2cRead(IntradayTime,4,wp.str);
	if(wp.dat<xp->dat)
	{//日期已经跨越到第2或第“N”天,中间未开机时间段的日交易签名没有处理
		i=DailySign();				//处理日交易签名
		//如果日交易签名不成功,程序会停在DailySign()中		
		DeclareAddUp();				//累加申报数据,清空日交易缓冲区
	}
	return 1;
}

void DataDispose()
{
	uchar fiscalcode[10];
	uint adr;
	gyt4 fp;	

	if(PwrFlg==1)
		PowerOffHint("没有生成税控码!","本次交易数据作废!",0xAA);
	//-------------------------------------------------------------------------
	#if DebugSim
	AutoDailySign();
	if(PwrFlg==1)
		PowerOffHint("没有生成税控码!","本次交易数据作废!",0xAA);	
	#endif
	//-------------------------------------------------------------------------
	//废票数据在BlankOutInvoice中处理
	//-------------------------------------------------------------------------
	if(DailyDatCheck()==0)return;
	if(DeadlineCheck()==0)return;
	#if DebugSim
	GetFiscalCode(fiscalcode);
	#endif
	InvoiceStorage(fiscalcode);			//发票打印数据存储
	InvoNoInc(CurInvoNo,1);
	DailyDatAddUp();					//日交易数据累加(正常发票和退票)
	if(InvoiceFlg==1 && SalerNo!=0)		//退票时不累加营业员销售金额
	{//如果营业员编号为0,不累加
		adr=SalerStat+(SalerNo-1)*4;
		I2cRead(adr,4,fp.str);
		fp.dat += WareTotalPrice;		//营业员销售金额累加
		I2cWrite(adr,4,fp.str);
	}
	if(PwrFlg==1)
		PowerOffHint("税控码已经生成!","发票尚未打印!",0xAA);
	PrintInvoice(fiscalcode);			//掉电时如何处理发票打印?
}

void SetIndex()
{
	uchar i,dat[8];
	//暂定6种税率
	memset(WareClassStat,0,sizeof(WareClassStat));
	I2cRead(IndexItems,6,dat);
	for(i=0;i<6;i++)
	{
		WareClassStat[i*5]=dat[i];
	}
}

uchar SaleEnd()
{
	uchar k;

	while(1)
	{
		k=InvoiceCheck(1);
		if(k==1)break;
		if(k==0 || k==2)return 0;
		Hint(16,0,"没录入发票,不能销售!",3);
	}
	memset(WareList,0,sizeof(WareList));
	SetIndex();
	WareTotalPrice=0;
	WareClass=0;
	InvoiceFlg=1;
	SaleFlag=0;
	Surcharge=0;
	Discount=0;
	UntreadCode.dat=0;
	return 1;
}

void VfdShowPrice(ulong price)
{
	uchar str[25];

   	NumToStr(price,str,SwitchFloat);
	VfdDisplayInt(str,7,0);
}

uchar SubTotal()
{//小计
	uchar k,i,j;
	uint m;
	ulong money;
	gyt4 *tp,*xp,fp,hp;

	if(!BeginSale)
	{
		Beep(400);
		return 1;
	}
	if(SubtotalPress)
	{
		Beep(400);
		return 1;
	}
	else
	{
		SetSubtotal;
	}
	SCON2 &= 0xEF;				//禁止UART1接收,REN2=0
	IEA &= 0xEF;				//关UART1中断,ES2 = 0;
	for(k=0;k<WareClass;k++)
	{
		tp = &WareList[k][2];
		xp = &WareList[k][6];
		money = (xp->dat*tp->dat)/100;
		WareTotalPrice += money;		//总金额累加
		j = WareList[k][10];
		i=FindIndex(j);
		if(i==0xFF)
			ErrorHint("税种税目索引号出错!",0x3003);
		tp=&WareClassStat[i];			//分类统计金额累加
		tp->dat += money;
	}
	I2cRead(SingleQuota,4,fp.str);
	if(WareTotalPrice>fp.dat)
	{
		Hint(16,0,"超出单张发票金额限额!",3);
		return 0;
	}
	if(InvoiceFlg==1)
	{
		I2cRead(DecAddUp,4,fp.str);
		fp.dat+=WareTotalPrice;
		I2cRead(AddUpQuota,4,hp.str);
		if(fp.dat>hp.dat)
		{
			Hint(16,0,"超出发票累计金额限额!",3);
			return 0;
		}
	}
	else
	{
		I2cRead(DecUntread,4,fp.str);
		fp.dat+=WareTotalPrice;
		I2cRead(UntreadQuota,4,hp.str);
		if(fp.dat>hp.dat)
		{
			Hint(16,0,"超出退票累计金额限额!",3);
			return 0;
		}
	}
	WindowsSet(0);
	strcpy(&WinHint[0][1],"小计:");
	NumToStr(WareTotalPrice,&WinHint[0][6],1);
	strcpy(&WinHint[1][1],"总计:");
	NumToStr(WareTotalPrice,&WinHint[1][6],1);
	strcpy(&WinHint[2][1],"现金:");
	strcpy(&WinHint[3][1],"找钱:");

	VfdShowPrice(WareTotalPrice);

	k=0;
	while(1)
	{
		if(k!=0xF0)
		{
			LcdDisplay(0,0,&WinHint[0][1],3);
			LcdDisplay(16,0,&WinHint[1][1],1);
			LcdDisplay(32,0,&WinHint[2][1],1);
			LcdDisplay(48,0,&WinHint[3][1],1);
		}
		//加上滚动条
		if(k==0 || k==0xF0)
		{
			k=WaitKey(32,40);
		}
		if(k == K_TC)
		{
			ClrSubtotal;
			ClrTotalAbate;
			ClrTotalExcess;
			WareTotalPrice=0;
			for(i=0;i<6;i++)
			{
				xp=&WareClassStat[i*5+1];
				xp->dat=0;
			}
			Discount=0;
			Surcharge=0;
			VfdClear();
			return 1;
		}
		m=KeyDat(k);
		if(m!=0xFF)
		{
			money=GetPrice(32,40,m*100);
			if(money==0)
			{
				k=K_TC;
				continue;
			}
			money = money-WareTotalPrice;
			NumToStr(money,&WinHint[3][6],1);
			LcdDisplay(48,0,&WinHint[3][1],1);		//显示找钱
			VfdShowPrice(money);		//VFD显示找钱

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -