📄 sale.c
字号:
/*
* 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 + -