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

📄 sale.bak

📁 用keil开发的.单片机税控器程序.单片机用的是AT公司的.upsd3245
💻 BAK
📖 第 1 页 / 共 4 页
字号:
/*
* Copyright (c) 2004,成都港顺科技发展有限公司
* All rights reserved.
*
* 编 译 器:Keil:C Compiler:7.20;Assembler:7.10
* 工程名称:POS-Test.UV2
* 文件名称:Sale.C
* 摘    要:销售流程和税务数据处理
*
* 单 片 机:uPSD3254
* 当前版本:0.4
* 作    者:李凯
* 完成日期:2004-12-7 14:45
*/

#include "Main.h"

#define ItemShift		(SaleFlag & 0x0001)
#define NewPrice		(SaleFlag & 0x0002)
#define DotPress		(SaleFlag & 0x0004)
#define AbatePress		(SaleFlag & 0x0008)
#define ExcessPress		(SaleFlag & 0x0010)
#define SubtotalPress	(SaleFlag & 0x0020)
#define PluPress		(SaleFlag & 0x0040)
#define ItemPress		(SaleFlag & 0x0080)
#define NumberPress		(SaleFlag & 0x0100)
#define BeginSale		(SaleFlag & 0x0200)
#define TotalAbate		(SaleFlag & 0x0400)
#define TotalExcess		(SaleFlag & 0x0800)
#define CashIncome		(SaleFlag & 0x1000)
#define Saleing			(SaleFlag & 0x2000)

#define SetShift		SaleFlag |= 0x0001
#define SetNewPrice		SaleFlag |= 0x0002
#define SetDot			SaleFlag |= 0x0004
#define SetAbate		SaleFlag |= 0x0008
#define SetExcess		SaleFlag |= 0x0010
#define SetSubtotal		SaleFlag |= 0x0020
#define SetPlu			SaleFlag |= 0x0040
#define SetItem			SaleFlag |= 0x0080
#define SetNumber		SaleFlag |= 0x0100
#define SetSale			SaleFlag |= 0x0200
#define SetTotalAbate	SaleFlag |= 0x0400
#define SetTotalExcess	SaleFlag |= 0x0800
#define SetCash			SaleFlag |= 0x1000
#define SetSaleing		SaleFlag |= 0x2000

#define ClrShift		SaleFlag &= 0xFFFE
#define ClrNewPrice		SaleFlag &= 0xFFFD
#define ClrDot			SaleFlag &= 0xFFFB
#define ClrAbate		SaleFlag &= 0xFFF7
#define ClrExcess		SaleFlag &= 0xFFEF
#define ClrSubtotal		SaleFlag &= 0xFFDF
#define ClrPlu			SaleFlag &= 0xFFBF
#define ClrItem			SaleFlag &= 0xFF7F
#define ClrNumber		SaleFlag &= 0xFEFF
#define ClrSale			SaleFlag &= 0xFDFF
#define ClrTotalAbate	SaleFlag &= 0xFBFF
#define ClrTotalExcess	SaleFlag &= 0xF7FF
#define ClrCash			SaleFlag &= 0xEFFF
#define ClrSaleing		SaleFlag &= 0xDFFF

volatile uchar xdata	WinHint[12][26];
volatile uchar xdata	WinDat[12][26];//WinVfd[12][3],窗体函数参数
volatile uchar xdata	WareList[ClassMaxNum][11];	//商品销售明细:编号2字节,价格4字节,数量4字节,税种税目索引号1字节
volatile uchar xdata	WareClassStat[30];			//发票分类金额,按税种税目分类,每类5字节
volatile uchar xdata	InvoDate[8];				//时间
volatile gyt4 xdata 	UntreadCode;				//退票
volatile uchar xdata	WareClass;					//已经销售的商品的种类类
volatile uchar xdata	SalerNo;					//收款员编号
volatile ulong xdata	WareNo;						//当前商品编号
volatile ulong xdata	WareTotalPrice;				//本张发票销售总金额,收入现金
volatile ulong xdata	Surcharge,Discount;			//整体加费总金额、整体打折总金额
volatile uchar xdata	InvoiceFlg;					//退货标志,废票标志
volatile ulong xdata 	CurInvoNo;					//当前发票号,掉电后需要保存,加效验码

volatile uint xdata SaleFlag;						//销售标志位:
//bit0:项目换档,0:项目1-25; 1:项目26-50
//bit1:默认价格标志,0:默认价格; 1:手工输入价格
//bit2:小数点按下标志,0:没有按下; 1:已经按下
//bit3:打折标志,0:打折键没有按下;1:已经按下
//bit4:加费标志,0:加费键没有按下;1:已经按下
//bit5:小计按下标志,0:没有按下;1:已经按下
//bit6:PLU按下标志,0:没有按下;1:已经按下
//bit7:项目按下标志,0:没有按下;1:已经按下
//bit8:数量按下标志,0:没有按下;1:已经按下
//bit9:第一次销售标志,0:没有开始销售;1:开始销售了
//bit10:整体打折标记,0:没有整体打折;1:已经整体打折
//bit11:整体加费标记,0:没有整体加费;1:已经整体加费
//bit12:现金输入标记,0:现金与实际价格相同;1:现金大于实际价格
//bit13:销售进行标志,0:本次交易结束等待下一次交易开始,1:交易进行中

void Munit(unsigned char k,unsigned char *tp)
{
	switch(k)
	{
		case 1:		tp[0]=0xB7;tp[1]=0xD6;		break;	//"分"
		case 2:		tp[0]=0xBD;tp[1]=0xC7;		break;	//"角"
		case 3:		tp[0]=0xD4;tp[1]=0xAA;		break;	//"元"
		case 4:		tp[0]=0xCA;tp[1]=0xB0;		break;	//"拾"
		case 5:		tp[0]=0xB0;tp[1]=0xDB;		break;	//"佰"
		case 6:		tp[0]=0xC7;tp[1]=0xAA;		break;	//"仟"
		case 7:		tp[0]=0xCD;tp[1]=0xF2;		break;	//"万"
		case 8:		tp[0]=0xCA;tp[1]=0xB0;		break;	//"拾"
		default :	tp[0]=0;tp[1]=0;			break;
	}
}

void NumToChinese(unsigned char k,unsigned char *xp)
{
	switch(k)
	{
		case '0':	xp[0]=0xC1;xp[1]=0xE3;		break;	//"零"
		case '1':	xp[0]=0xD2;xp[1]=0xBC;		break;	//"壹"
		case '2':	xp[0]=0xB7;xp[1]=0xA1;		break;	//"贰"
		case '3':	xp[0]=0xC8;xp[1]=0xFE;		break;	//"叁"
		case '4':	xp[0]=0xCB;xp[1]=0xC1;		break;	//"肆"
		case '5':	xp[0]=0xCE;xp[1]=0xE9;		break;	//"伍"
		case '6':	xp[0]=0xC2;xp[1]=0xBD;		break;	//"陆"
		case '7':	xp[0]=0xC6;xp[1]=0xE2;		break;	//"柒"
		case '8':	xp[0]=0xB0;xp[1]=0xC6;		break;	//"捌"
		case '9':	xp[0]=0xBE;xp[1]=0xC1;		break;	//"玖"
		default :	xp[0]=0;xp[1]=0;			break;
	}
}

void NumToCash(unsigned long x,unsigned char *p)
{
	unsigned char i,t[25],k,j,xp[4];

	memset(t,0,sizeof(t));
	NumToStr(x,t,SwitchInt);
	k=strlen(t);
	if(k>8)
	{
		Beep(400);
		return;
	}
	for(i=0;i<k;i++)
	{
		NumToChinese(t[i],xp);
		j=i*4;
		p[j]=xp[0];
		p[j+1]=xp[1];
		Munit(k-i,xp);
		p[j+2]=xp[0];
		p[j+3]=xp[1];
	}
}

uchar TimeIncDec(uchar x,uchar v)
{
	uchar m,n;
	
	n=x>>4;
	m=n*10+(x&0x0F);
	if(v==1)m++;		
	else	m--;
	x=m/10;
	x<<=4;
	x|=(m%10);
	return x;	
}

ulong CalculateTime(ulong time,uchar x)
{//x=0:计算前一天;x=1:计算后一天
	gyt4 tp;	
	uchar m=0;
	uint xp=0;
	
	tp.dat=time;
	xp=(tp.str[0]>>4)*10;
	xp+=(tp.str[0]&0x0F);
	xp*=100;
	xp+=(tp.str[1]>>4)*10;
	xp+=(tp.str[1]&0x0F);//判断是否闰年时必须将时间从BCD格式转换为十进制

	if(x==0)
	{
		if(tp.str[3]!=1)
		{//不是每月的一号
			tp.str[3]=TimeIncDec(tp.str[3],0);
			return tp.dat;
		}
		else
		{//是每月的一号
			switch(tp.str[2])
			{
				case	0x01:	tp.str[1]=TimeIncDec(tp.str[1],0);
								tp.str[2]=0x12;tp.str[3]=0x31;
								return tp.dat;				
				case	0x05:
				case	0x07:				
				case	0x10:
				case	0x12:	tp.str[2]=TimeIncDec(tp.str[2],0);;
								tp.str[3]=0x30;
								return tp.dat;
				case	0x03:	if(((xp%4==0) && (xp%100!=0)) || (xp%400==0))
									m=1;//闰年
								else								
									m=0;								
								tp.str[2]=0x02;
								tp.str[3]=0x28+m;								
								return tp.dat;								
				case	0x08:		
				case	0x02:
				case	0x04:
				case	0x06:
				case	0x09:
				case	0x11:	tp.str[2]=TimeIncDec(tp.str[2],0);
								tp.str[3]=0x31;
								return tp.dat;
				default	:	ErrorHint("时间格式错误!",190);;
			}
		}
	}
	else
	{
		switch(tp.str[2])
		{
			case	0x01:
			case	0x03:
			case	0x05:
			case	0x07:
			case	0x08:
			case	0x10: 	if(tp.str[3]<0x31)m=3;
							else	m=2;
							tp.str[m]=TimeIncDec(tp.str[m],1);
							if(m==2)tp.str[3]=0x01;
							return tp.dat;

			case	0x12:	if(tp.str[3]<0x31)m=3;
							else	m=1;
							tp.str[m]=TimeIncDec(tp.str[m],1);
							if(m==1)
							{
								tp.str[2]=0x01;
								tp.str[3]=0x01;
							}
							return tp.dat;							

			case	0x02:  	if(((xp%4==0) && (xp%100!=0)) || (xp%400==0))							
								m=1;//闰年							
							else
								m=0;
							m+=0x28;				
							if(tp.str[3]<m)
							{
								tp.str[3]=TimeIncDec(tp.str[3],1);
								return tp.dat;
							}
							else
							{
								tp.str[2]=0x03;
								tp.str[3]=0x01;
								return tp.dat;
							}
			case	0x04:
			case	0x06:
			case	0x09:
			case	0x11:	if(tp.str[3]<0x30)m=3;
							else	m=2;
							tp.str[m]=TimeIncDec(tp.str[m],1);
							if(m==2)tp.str[3]=0x01;
							return tp.dat;							

			default	:	ErrorHint("时间格式错误!",191);
		}
	}
}

uchar KeyDat(uchar dat)
{
	switch(dat)
	{
		case K_0	:	return 0;
		case K_1	:	return 1;
		case K_2	:	return 2;
		case K_3	:	return 3;
		case K_4	:	return 4;
		case K_5	:	return 5;
		case K_6	:	return 6;
		case K_7	:	return 7;
		case K_8	:	return 8;
		case K_9	:	return 9;
		default		:	return 0xFF;
	}
}

void SetKey(uchar *key)
{
	key[0]=K_SL;
	key[1]=K_JF;
	key[2]=K_DZ;
	key[3]=K_XM1;
	key[4]=K_XM2;
	key[5]=K_XM3;
	key[6]=K_XM4;
	key[7]=K_XM5;
	key[8]=K_XM6;
	key[9]=K_XM7;
	key[10]=K_XM8;
	key[11]=K_XM9;
	key[12]=K_XM10;
	key[13]=K_XM11;
	key[14]=K_XM12;
	key[15]=K_XM13;
	key[16]=K_XM14;
	key[17]=K_XM15;
	key[18]=K_XM16;
	key[19]=K_XM17;
	key[20]=K_XM18;
	key[21]=K_XM19;
	key[22]=K_XM20;
	key[23]=K_XM21;
	key[24]=K_XM22;
	key[25]=K_XM23;
	key[26]=K_XM24;
	key[27]=K_XM25;
	key[28]=K_JZ;
	key[29]=K_TZ;
	key[30]=K_BZ;
	key[31]=K_CX;
	key[32]=K_PLU;
	key[33]=K_HD;
	key[34]=K_TC;
	key[35]=K_XJ;
	key[36]=K_TM;
	key[37]=0;
}

ulong GetPrice(uchar lx,uchar ly,uint m)
{
	ulong money;
	uchar pi[2];

	if(m==0xFF){Beep(500);m=0;return 0;}
	while(1)
	{
		pi[0]=0;
		money=GetFloat(lx,ly,m,8,pi);
		if(pi[0]==K_TC)return 0;
		if(money==0)
		{
			LcdDisplay(lx,(ly+88),"不能为0 ",0);
			continue;
		}
		if(money<WareTotalPrice)
//		if(money<(WareTotalPrice+Surcharge-Discount))
		{
			LcdDisplay(lx,(ly+88),"金额太小",0);
			m=0;
			continue;
		}
		return money;
	}
}

void PtintInvoTome(uchar *str)
{//自动打印发票使用汇总数据报表
	gyt4 *xp;
	uchar dat[51];

	memset(dat,0,sizeof(dat));
	PrintStr("---------单卷发票使用汇总数据报表---------");
	strcpy(dat,"单位名称:");
	I2cRead(TaxpayerName,40,&dat[9]);
	dat[40]=0;
	PrintStr(dat);								//单位名称
	
	memset(dat,0,sizeof(dat));
	strcpy(dat,"税号:");
	I2cRead(TaxNumber,20,&dat[5]);
	dat[26]=0;
	PrintStr(dat);								//税号

	memset(dat,0,sizeof(dat));
	I2cRead(MachineNo,8,dat);
	dat[8]=0;
	PrintCodeNum("机器编号:",1,dat,8);			//机器编号

	PrintStartToEnd(&str[29]);					//开票时间

	PrintCodeNum("发票代码:",1,str,10);			//打印发票代码
	xp=&str[10];
	PrintStrNum("发票起始号:",xp->dat,0x02);		//打印发票起始号
	xp=&str[14];
	PrintStrNum("发票终止号:",xp->dat,0x02);		//打印发票终止号
	PrintStrNum("正常发票份数:",str[18],0x02);		//打印正常发票份数
	xp=&str[21];
	PrintStrNum("正常发票总金额:",xp->dat,0x03);	//打印正常发票总金额
	PrintStrNum("废票份数:",str[20],0x02);			//打印废票份数
	PrintStrNum("退票份数:",str[19],0x02);			//打印退票份数
	xp=&str[25];
	PrintStrNum("退票总金额:",xp->dat,0x03);		//打印退票总金额
	PrintStr("      电子存根");
	PrintStr("-------------------------------------");
	PrintHome();
}

void SaleQuery()
{
	uchar x,i,j,n,m,mode,str[10],dat[10];
	gyt4 *xp,*tp;
	gyt2 *hp,*fp;
	ulong adr,num,price;
	uint no;

	if(WareClass==0)
	{
		Hint(16,32,"没有销售数据!",3);
		return;
	}
	while(1)
	{
		WindowsSet(0);
		for(i=0;i<WareClass;i++)
		{
			WinHint[i][0]=1;					//本行有提示内容
			WinHint[i][1]=i+0x31;				//显示序号: 1 to 12
			WinHint[i][2]='.';
			WinDat[i][0]=0;						//本行没有输入
			fp = &WareList[i][0];
			no = fp->dat;
			if((no & 0xFF00) == 0xFF00)
			{
				no -= 0xFF00;
				adr = (no-1)*33 + ItemAdr;		//项目、部类
				SerialFlashRead(FlashDat,adr,16,&WinHint[i][3]);
			}
			else
			{
				adr = (no-1)*39 + WareAdr;		//PLU
				SerialFlashRead(FlashDat,adr,16,&WinHint[i][3]);
			}
		}

		str[0]=K_LJ;							//订正键
		str[1]=K_QC;							//清除键
		str[2]=K_TC;
		str[3]=K_HJ;
		str[4]=0;
		m = Windows(1,0,str)-1;
		if(str[0] == K_TC)return;
		if(str[0] == K_QC)
		{
			LcdDisplay(0,0,"确实要删除本商品吗?",3);
			LcdDisplay(16,0,"---按<确认>删除!",0);
			LcdDisplay(32,0,"---按其它键取消!",0);
			n=KeyScan();
			if(n==K_HJ)
			{
				for(i=m;i<WareClass;i++)
					for(j=0;j<11;j++)
						WareList[i][j]=WareList[i+1][j];
				WareClass -= 1;
				Hint(16,32,"删除成功!",3);
				if(WareClass==0)return;
				continue;
			}
		}
		if(str[0] == K_HJ)mode=1;
//		if(str[0] == K_LJ)
		else
			mode=2;
		//--------------------------------------------------------
		for(i=0;i<16;i++)
			TxdBuf[i]=WinHint[m][3+i];			//赋值顺序不能改变
		WindowsSet(5);
		strcpy(&WinHint[1][1],"名称:");			//赋值顺序不能改变
		for(i=0;i<16;i++)
			WinHint[1][6+i]=TxdBuf[i];			//赋值顺序不能改变
		//--------------------------------------------------------
		fp = &WinDat[0][2];						//编号
		hp = &WareList[m][0];
		fp->dat = hp->dat;
		if((fp->dat & 0xFF00) == 0xFF00)
			fp->dat &= 0x00FF;
		strcpy(&WinHint[0][1],"编号:");
		NumToStr(fp->dat,&WinHint[0][6],SwitchInt);
		//--------------------------------------------------------
		strcpy(&WinHint[2][1],"价格:");
		tp = &WareList[m][2];
		price = tp->dat;
		if(mode==1)
			NumToStr(price,&WinHint[2][6],SwitchFloat);
		else
		{
			WinDat[2][0]=2;			//允许输入小数,禁止扫描器输入
			WinDat[2][1]=8;			//允许输入小数的长度是8位
			xp = &WinDat[2][2];
			xp->dat = price;
		}
		//--------------------------------------------------------
		strcpy(&WinHint[3][1],"数量:");
		tp = &WareList[m][6];
		num = tp->dat;
		if(mode==1)
			NumToStr(num,&WinHint[3][6],SwitchFloat);
		else
		{
			WinDat[3][0]=2;			//允许输入小数,禁止扫描器输入
			WinDat[3][1]=6;			//允许输入小数的长度是6位
			xp = &WinDat[3][2];
			xp->dat = num;
		}
		//--------------------------------------------------------
		strcpy(&WinHint[4][1],"税种税目索引号:");
		WinHint[4][16]='0'+WareList[m][10];
		//--------------------------------------------------------
		if(mode==2)x=3;
		else	x=2;
		while(1)
		{
			dat[0]=K_DZ;
			dat[1]=K_TC;
			dat[2]=K_JF;
			dat[3]=K_SL;
			dat[4]=K_HJ;
			dat[5]=0;
			n = Windows(x,1,dat);
			if(dat[0] == K_TC)break;
			if(mode==2)
			{
				if(dat[0] == K_SL)
				{
					tp = &WinDat[3][2];
					tp->dat = 0;
					x=4;
					continue;
				}
				if(dat[0] == K_DZ || dat[0] == K_JF)
				{
					if(dat[0] == K_DZ)n=0;
					if(dat[0] == K_JF)n=1;
					tp = &WinDat[2][2];
					AmendPrice(n,0,tp->dat);
					price = tp->dat;	//打折之后是否保留原始价格?
					continue;
				}
				if(dat[0]==K_HJ)
				{
					tp = &WinDat[2][2];
					if(tp->dat==0)
					{
						Hint(16,48,"价格不能为0!",3);

⌨️ 快捷键说明

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