//---------------------------------------------------------------------------
// String _opacsconnection; 约定的输入变量名
// String _hisconnection; 	约定的输入变量名
// String _modalitytype; 	约定的输入变量名
// bool _ischarging; 		约定的输入变量名
// TADOQuery _qryStudy 	 	外部已定义的对象
// TADOQuery _qryCustom	 	外部已定义的对象
// TADOQuery _qryPriceList  外部已定义的对象
// TADOQuery _qryPriceCombo 外部已定义的对象
// TADOQuery _qryBillDetail 外部已定义的对象
// TADOQuery _qryHisCustom  外部已定义的对象
// TADOQuery _qryHisCommon  外部已定义的对象
//
// 脚本必须实现的函数 int _CanCharging();
// 脚本必须实现的函数 double _CalcSpareMoney();
// 脚本必须实现的函数 double _InitCharging();
// 脚本必须实现的函数 int _FillPriceList(); 	
// 脚本必须实现的函数 int _FillPriceCombo(); 	
// 脚本必须实现的函数 double _AppendBillCombo();
// 脚本必须实现的函数 double _AppendBillDetail();
// 脚本必须实现的函数 double _DeleteBillDetail();
// 脚本必须实现的函数 double _ClearBillDetail();
// 脚本必须实现的函数 int _CommitCharging();
// 脚本必须实现的函数 int _RefundCharging();
//---------------------------------------------------------------------------

#include "..\\Common\\HisCommon.cpp", "..\\Common\\JWCommon.cpp"

//String    _opacsconnection;
//String    _hisconnection;
//String 	_modalitytype;
bool 		_ischarging;

//---------------------------------------------------------------------------
// 自定义变量
String g_sPatientIDField = ""; 	// PATIENT_ID字段
String g_sBillDetail = "";		// 收费明细表表名
int g_iRefundRecordCount = 0; 	// 退费初始记录数
int g_iLeastMoney = 0;          // 最小预交金

//---------------------------------------------------------------------------
// 是否可以执行计费划价
//---------------------------------------------------------------------------
int _CanCharging()
{
	//g_sPatientIDField = "patient_guid"; // 超声等科室使用，请根据情况配置。
	g_sPatientIDField = "study_guid"; // 放射等科室使用，请根据情况配置。
	g_iLeastMoney = 0;                // 最小预交金，请根据情况配置。
    
    String sStudySource = _qryStudy.FieldByName("study_source").AsString;
    if (sStudySource == "住院")
    {
    	if (_ischarging)
    	{
    		// 收费时余额判断
			String sPatientGuid = _qryStudy.FieldByName(g_sPatientIDField).AsString;
    		double fSpaceMoney = CalcSpaceMoney(sPatientGuid);
	    	if (fSpaceMoney >= g_iLeastMoney)
				return 1;
            else
            {
				MessageBox("余额少于最小预交金,请立即缴费！", "电子申请单", 1);
				return 1;   // 此处如果不允许划价不太合理
            }
    	}    	
	  	return 1;
  	}
	else
	{
		MessageBox("非住院病人，不允许执行收费退费！", "电子申请单", 1);
		return 0;            
    }     	
}

//---------------------------------------------------------------------------
// 计算本次检查后余额
//---------------------------------------------------------------------------
double _CalcSpareMoney()
{
    String sPatientGuid = _qryStudy.FieldByName(g_sPatientIDField).AsString;
	double fStudyCharge = _qryStudy.FieldByName("study_charge").AsFloat;
    double fTotalExamCharge = CalcTotalExamCharge(_qryBillDetail);
    double fSpaceMoney = CalcSpaceMoney(sPatientGuid);
    double fResult = fSpaceMoney - (fStudyCharge + fTotalExamCharge);
    return fResult;
}

//---------------------------------------------------------------------------
// 初始化计费信息
//---------------------------------------------------------------------------
double _InitCharging()
{
	// 初始化变量
	g_sBillDetail = GetTableNameByIP("CC_BILLDETAIL");	// !!!
	////
	String sHisQuery = "";
	if (_ischarging) // 初始化收费清单
	{
    	String sExamNo = _qryStudy.FieldByName("study_number0").AsString;  
		sHisQuery = "select c.AMOUNT,c.CHARGE_ITEM_CODE from clinic_vs_charge c left join EXAM_ITEMS e " +
							" on c.clinic_item_code = e.EXAM_ITEM_CODE";
		sHisQuery = AddWhereCondition(sHisQuery, "e.EXAM_NO = '" + sExamNo + "'");
	    _qryHisCustom.Close();
	    _qryHisCustom.SQL.Text = sHisQuery;
	    _qryHisCustom.Open();
	    ////
	    if (!_qryHisCustom.IsEmpty())
		{
			_qryHisCustom.First();
		    while (!_qryHisCustom.Eof)
		    {
		        String sItemCode = _qryHisCustom.FieldByName("CHARGE_ITEM_CODE").AsString;
		    	if (_qryPriceList.Locate("price_itemcode", sItemCode, 0))
		    	{
					_AppendBillDetail();
					////
					int iHisAmount = _qryHisCustom.FieldByName("AMOUNT").AsInteger; 
					if (iHisAmount > 1)
					{
						// 重新定位数据
						_qryBillDetail.Locate("bill_itemcode", sItemCode, 0);	
		    			int iAmount = _qryBillDetail.FieldByName("bill_amount").AsInteger;
					    double fExamCost = _qryBillDetail.FieldByName("bill_examcost").AsFloat;
					    double fExamCharge = _qryBillDetail.FieldByName("bill_examcharge").AsFloat;
					    // 根据数量修改价格
						_qryBillDetail.Edit();
				    	_qryBillDetail.FieldByName("bill_amount").Value = iAmount + iHisAmount - 1;
				    	_qryBillDetail.FieldByName("bill_examcharge").Value = fExamCharge / iAmount * (iAmount + iHisAmount - 1);
				    	_qryBillDetail.FieldByName("bill_examcost").Value = fExamCost / iAmount * (iAmount + iHisAmount - 1);
						_qryBillDetail.Post();
					}
				}
		        _qryHisCustom.Next();
		    }
		}
	}
	else // 初始化退费清单
	{
	String sPatientGuid = _qryStudy.FieldByName(g_sPatientIDField).AsString;
    double fStudyCharge = _qryStudy.FieldByName("study_charge").AsFloat;
    
	// 计算最大号
	int iMaxVisitID = GetMaxVisitID(sPatientGuid);
	
	// 计算sPerformer
	String sLoginDepartment = GetConfigStr("SysLogon", "sLastDepartment");
	String sPerformer = GetDeptCode(sLoginDepartment);    
		////
		sHisQuery = "SELECT * FROM INP_BILL_DETAIL";
		sHisQuery = AddWhereCondition(sHisQuery, "PERFORMED_BY = '" + sPerformer + "'");
		sHisQuery = AddWhereCondition(sHisQuery, "PATIENT_ID = '" + sPatientGuid + "'");
		sHisQuery = AddWhereCondition(sHisQuery, "VISIT_ID = " + IntToStr(iMaxVisitID));
	    _qryHisCustom.Close();
	    _qryHisCustom.SQL.Text = sHisQuery;
	    _qryHisCustom.Open();
	    ////
	    if (_qryHisCustom.IsEmpty())
	    {
			double fSpaceMoney = CalcSpaceMoney(sPatientGuid);
			return fSpaceMoney - fStudyCharge;
		}
		else
		{
			_qryHisCustom.First();
		    while (!_qryHisCustom.Eof)
		    {
		        _qryBillDetail.Append();
		        _qryBillDetail.FieldByName("bill_patientid").Value = _qryHisCustom.FieldByName("PATIENT_ID").AsString;
                _qryBillDetail.FieldByName("bill_visitid").Value = _qryHisCustom.FieldByName("VISIT_ID").AsInteger;
		        _qryBillDetail.FieldByName("bill_itemno").Value = _qryHisCustom.FieldByName("ITEM_NO").AsInteger;
			    _qryBillDetail.FieldByName("bill_examkind").Value = _qryHisCustom.FieldByName("ITEM_CLASS").AsString;
		        _qryBillDetail.FieldByName("bill_examname").Value = _qryHisCustom.FieldByName("ITEM_NAME").AsString;
		        _qryBillDetail.FieldByName("bill_amount").Value = _qryHisCustom.FieldByName("AMOUNT").AsInteger;
		        _qryBillDetail.FieldByName("bill_examcost").Value = _qryHisCustom.FieldByName("COSTS").AsFloat;
		        _qryBillDetail.FieldByName("bill_examcharge").Value = _qryHisCustom.FieldByName("CHARGES").AsFloat;
		        _qryBillDetail.FieldByName("bill_itemcode").Value = _qryHisCustom.FieldByName("ITEM_CODE").AsString;
			    _qryBillDetail.FieldByName("bill_itemspec").Value = _qryHisCustom.FieldByName("ITEM_SPEC").AsString;
		        _qryBillDetail.FieldByName("bill_itemunit").Value = _qryHisCustom.FieldByName("UNITS").AsString;
		        _qryBillDetail.FieldByName("bill_datetime").Value = _qryHisCustom.FieldByName("BILLING_DATE_TIME").AsDateTime;
			    _qryBillDetail.FieldByName("bill_requester").Value = _qryHisCustom.FieldByName("ORDERED_BY").AsString;
		        _qryBillDetail.FieldByName("bill_performer").Value = _qryHisCustom.FieldByName("PERFORMED_BY").AsString;
		        _qryBillDetail.FieldByName("bill_operator").Value = _qryHisCustom.FieldByName("OPERATOR_NO").AsString;
		        _qryBillDetail.Post();
		        ////
		        _qryHisCustom.Next();
		    }
		}
	}
    ////
    _qryBillDetail.Close();
    _qryBillDetail.SQL.Text = "SELECT * FROM " + g_sBillDetail;
    _qryBillDetail.Open();
    ////
    if (!_ischarging)
    {
    	g_iRefundRecordCount = GetRecordCount(_qryBillDetail);	
    }
	
	return _CalcSpareMoney();
}

//---------------------------------------------------------------------------
// 填充CC_PriceList价格表
//---------------------------------------------------------------------------
int _FillPriceList()
{
	// 计算sPerformer
	String sLoginDepartment = GetConfigStr("SysLogon", "sLastDepartment");
	String sPerformer = GetDeptCode(sLoginDepartment);
	////
	_qryPriceList.Close();
	_qryPriceList.SQL.Text = "DELETE FROM CC_PRICELIST";
	_qryPriceList.ExecSQL();
	_qryPriceList.SQL.Text = "SELECT * FROM CC_PRICELIST";
	_qryPriceList.Open();
	////
	String sHisQuery = "";
    int iFieldCount = 0;
    String sFieldPairs[2][100];
    SetArrayItem(sFieldPairs, iFieldCount, "price_examkind",	"ITEM_CLASS");
    SetArrayItem(sFieldPairs, iFieldCount, "price_examname", 	"ITEM_NAME");
    SetArrayItem(sFieldPairs, iFieldCount, "price_examcost", 	"PRICE");
    SetArrayItem(sFieldPairs, iFieldCount, "price_itemcode", 	"ITEM_CODE");
    SetArrayItem(sFieldPairs, iFieldCount, "price_inputcode", 	"INPUT_CODE");
    SetArrayItem(sFieldPairs, iFieldCount, "price_itemspec", 	"ITEM_SPEC");
    SetArrayItem(sFieldPairs, iFieldCount, "price_itemunit", 	"UNITS");
    ////
    if (IsConnetAccessDB(_hisconnection))
    {
    	sHisQuery = "SELECT CURRENT_PRICE_LIST.ITEM_CLASS, " + 
	    	"CURRENT_PRICE_LIST.ITEM_CODE, CURRENT_PRICE_LIST.ITEM_NAME, " + 
	    	"ITEM_SPEC, UNITS, PRICE, PREFER_PRICE, FOREIGNER_PRICE, " +
	    	"PERFORMED_BY, FEE_TYPE_MASK, CLASS_ON_INP_RCPT, CLASS_ON_OUTP_RCPT, " + 
	    	"CLASS_ON_RECKONING, SUBJ_CODE, CLASS_ON_MR, MEMO, OPERATOR, ENTER_DATE, INPUT_CODE " + 
			"FROM CURRENT_PRICE_LIST, PRICE_ITEM_NAME_DICT " + 
			"WHERE CURRENT_PRICE_LIST.ITEM_CODE=PRICE_ITEM_NAME_DICT.ITEM_CODE " + 
			"";//"AND CURRENT_PRICE_LIST.PERFORMED_BY = '" + sPerformer + "'";
	}
	else
	{
		sHisQuery = "SELECT CURRENT_PRICE_LIST.ITEM_CLASS, " + 
	    	"CURRENT_PRICE_LIST.ITEM_CODE, CURRENT_PRICE_LIST.ITEM_NAME, " + 
	    	"ITEM_SPEC, UNITS, PRICE, PREFER_PRICE, FOREIGNER_PRICE, " +
	    	"PERFORMED_BY, FEE_TYPE_MASK, CLASS_ON_INP_RCPT, CLASS_ON_OUTP_RCPT, " + 
	    	"CLASS_ON_RECKONING, SUBJ_CODE, CLASS_ON_MR, MEMO, OPERATOR, ENTER_DATE, INPUT_CODE " + 
			"FROM CURRENT_PRICE_LIST, PRICE_ITEM_NAME_DICT " + 
			"WHERE CURRENT_PRICE_LIST.ITEM_CODE=PRICE_ITEM_NAME_DICT.ITEM_CODE " + 
			"";//"AND CURRENT_PRICE_LIST.PERFORMED_BY = '" + sPerformer + "'";
	}
    _qryHisCustom.Close();
  	_qryHisCustom.SQL.Text = sHisQuery;
  	try
  	{
  		_qryHisCustom.Open();
  	}
  	except
    {
        ShowMessage("当前价目表查询失败！");
        return 0;
    }
    ////
  	if (!_qryHisCustom.IsEmpty())
    {
        _qryHisCustom.First();
        while (!_qryHisCustom.Eof)
        {
            _qryPriceList.Append();
            for (int i = 0; i < iFieldCount; i++)
            {
                if (!_qryHisCustom.FieldByName(sFieldPairs[1][i]).IsNull)
                    _qryPriceList.FieldByName(sFieldPairs[0][i]).Value =
                        _qryHisCustom.FieldByName(sFieldPairs[1][i]).Value;
            }
            _qryPriceList.Post();
            _qryHisCustom.Next();
        }
        ////
	    _qryPriceList.First();
	}

	MessageBox("更新当前价目表成功！", "电子申请单",1);
    return 1;
}

//---------------------------------------------------------------------------
// 填充CC_PriceCombo套餐价格表
//---------------------------------------------------------------------------
int _FillPriceCombo()
{
	// 计算sPerformer
	String sLoginDepartment = GetConfigStr("SysLogon", "sLastDepartment");
	String sPerformer = GetDeptCode(sLoginDepartment);
	////
	_qryPriceCombo.Close();
	_qryPriceCombo.SQL.Text = "DELETE FROM CC_PRICECOMBO";
	_qryPriceCombo.ExecSQL();
	_qryPriceCombo.SQL.Text = "SELECT * FROM CC_PRICECOMBO";
	_qryPriceCombo.Open();
	////
    int iFieldCount = 0;
    String sFieldPairs[2][100];
    SetArrayItem(sFieldPairs, iFieldCount, "COMBO_EXAMKIND", 	"PERFORMED_BY"); // for debug!
    SetArrayItem(sFieldPairs, iFieldCount, "COMBO_EXAMNAME", 	"PATTERN_NAME");
    SetArrayItem(sFieldPairs, iFieldCount, "COMBO_ITEMCODE", 	"SERIAL_NO"); // for debug!
    SetArrayItem(sFieldPairs, iFieldCount, "COMBO_INPUTCODE", 	"INPUT_CODE");
    ////
	String sHisQuery = "SELECT * FROM BILL_PATTERN_MASTER WHERE PERFORMED_BY = '" + sPerformer + "'";
    _qryHisCustom.Close();
  	_qryHisCustom.SQL.Text = sHisQuery;
  	try
  	{
  		_qryHisCustom.Open();
  	}
  	except
    {
        ShowMessage("套餐价目表查询失败！");
        return 0;
    }
    ////
  	if (!_qryHisCustom.IsEmpty())
    {
        _qryPriceCombo.First();
        while (!_qryHisCustom.Eof)
        {
            _qryPriceCombo.Append();
            for (int i = 0; i < iFieldCount; i++)
            {
                if (!_qryHisCustom.FieldByName(sFieldPairs[1][i]).IsNull)
                    _qryPriceCombo.FieldByName(sFieldPairs[0][i]).Value =
                        _qryHisCustom.FieldByName(sFieldPairs[1][i]).Value;
            }
            _qryPriceCombo.Post();
            _qryHisCustom.Next();
        }
        ////
	    _qryPriceCombo.First();
	}

	MessageBox("更新套餐价目表成功！", "电子申请单",1);
	return 1;
}

//---------------------------------------------------------------------------
// 增加CC_BillDetail表记录，增加单项
//---------------------------------------------------------------------------
double _AppendBillDetail()
{
	// 初始化变量
    String sPatientGuid = _qryStudy.FieldByName(g_sPatientIDField).AsString;
	String sExamKind = _qryPriceList.FieldByName("price_examkind").AsString;
	String sExamName = _qryPriceList.FieldByName("price_examname").AsString;
    double fExamCost = _qryPriceList.FieldByName("price_examcost").AsFloat;
	String sItemCode = _qryPriceList.FieldByName("price_itemcode").AsString;
	String sItemSpec = _qryPriceList.FieldByName("price_itemspec").AsString;
	String sItemUnit = _qryPriceList.FieldByName("price_itemunit").AsString;
	
	// 计算记录数
    int iRecordCount = GetRecordCount(_qryBillDetail);
    
    // 计算最大号
    int iMaxVisitID = GetMaxVisitID(sPatientGuid);
    int iMaxItemNo = GetMaxItemNo(sPatientGuid, iMaxVisitID);
    
    // 计算fExamCharge
    String sChargeType = GetChargeType(sPatientGuid, iMaxVisitID);
    String sInsuranceType = GetInsuranceType(sPatientGuid, iMaxVisitID);
    double fExamCharge = CalcExamCharge(fExamCost, sChargeType, sInsuranceType, 
    	sExamKind, sItemCode, sItemSpec);
    
    // 计算sRequester
    String sStudyDepartment = _qryStudy.FieldByName("study_department").AsString;
    String sRequester = GetDeptCode(sStudyDepartment);
    
    // 计算sPerformer
    String sLoginDepartment = GetConfigStr("SysLogon", "sLastDepartment");
    String sPerformer = GetDeptCode(sLoginDepartment);
    
    // 计算sOperator
    String sLoginDoctor = GetConfigStr("SysLogon", "sLastDoctorName");
    String sOperator = GetUserID(sLoginDepartment, sLoginDoctor);
    
    // 添加收费记录
    String sQuery = "SELECT * FROM " + g_sBillDetail;
    sQuery = AddWhereCondition(sQuery, "bill_examkind = '" + sExamKind + "'");
    sQuery = AddWhereCondition(sQuery, "bill_itemcode = '" + sItemCode + "'");
    _qryBillDetail.Close();
    _qryBillDetail.SQL.Text = sQuery;
    _qryBillDetail.Open();
    if (_qryBillDetail.IsEmpty())
	{
    	int iNewItemNo = iMaxItemNo + iRecordCount + 1;
    	
	    // 添加新收费记录
	    _qryBillDetail.Append();
	    _qryBillDetail.FieldByName("bill_patientid").Value = sPatientGuid;
	    _qryBillDetail.FieldByName("bill_visitid").Value = iMaxVisitID;
	    _qryBillDetail.FieldByName("bill_itemno").Value = iNewItemNo;
	    _qryBillDetail.FieldByName("bill_examkind").Value = sExamKind;
	    _qryBillDetail.FieldByName("bill_examname").Value = sExamName;
	    _qryBillDetail.FieldByName("bill_examcost").Value = fExamCost;
	    _qryBillDetail.FieldByName("bill_examcharge").Value = fExamCharge; 
	    _qryBillDetail.FieldByName("bill_itemcode").Value = sItemCode;
	    _qryBillDetail.FieldByName("bill_itemspec").Value = sItemSpec;
	    _qryBillDetail.FieldByName("bill_itemunit").Value = sItemUnit;
	    _qryBillDetail.FieldByName("bill_amount").Value = 1;
	    _qryBillDetail.FieldByName("bill_datetime").Value = Now();
	    _qryBillDetail.FieldByName("bill_requester").Value = sRequester;
	    _qryBillDetail.FieldByName("bill_performer").Value = sPerformer;
	    _qryBillDetail.FieldByName("bill_operator").Value = sOperator;
	    _qryBillDetail.Post();
    }
    else
    {
    	int iAmount = _qryBillDetail.FieldByName("bill_amount").AsInteger;
    	
    	// 添加已有收费项目
    	_qryBillDetail.Edit();
    	_qryBillDetail.FieldByName("bill_amount").Value = iAmount + 1;
    	_qryBillDetail.FieldByName("bill_examcharge").Value = fExamCharge * (iAmount + 1);
    	_qryBillDetail.FieldByName("bill_examcost").Value = fExamCost * (iAmount + 1);
    	_qryBillDetail.FieldByName("bill_datetime").Value = Now();
	    _qryBillDetail.FieldByName("bill_requester").Value = sRequester;
	    _qryBillDetail.FieldByName("bill_performer").Value = sPerformer;
	    _qryBillDetail.FieldByName("bill_operator").Value = sOperator;
    	_qryBillDetail.Post();
    }
    ////
	_qryBillDetail.Close();
	_qryBillDetail.SQL.Text = "SELECT * FROM " + g_sBillDetail;
	_qryBillDetail.Open();

    return _CalcSpareMoney();
}

//---------------------------------------------------------------------------
// 增加CC_BillDetail表记录，增加套餐
//---------------------------------------------------------------------------
double _AppendBillCombo()
{
	String sItemName = _qryPriceCombo.FieldByName("COMBO_EXAMNAME").AsString;
	String sHisQuery = "SELECT * FROM BILL_PATTERN_DETAIL WHERE PATTERN_NAME = '" + sItemName + "'";
    _qryHisCustom.Close();
    _qryHisCustom.SQL.Text = sHisQuery;
    _qryHisCustom.Open();
    ////
    _qryHisCustom.First();
    while (!_qryHisCustom.Eof)
    {
    	String sItemCode = _qryHisCustom.FieldByName("ITEM_CODE").AsString;
    	if (_qryPriceList.Locate("price_itemcode", sItemCode, 0))
    	{
			_AppendBillDetail();
			////
			int iHisAmount = _qryHisCustom.FieldByName("AMOUNT").AsInteger; 
			if (iHisAmount > 1)
			{
				// 重新定位数据
				_qryBillDetail.Locate("bill_itemcode", sItemCode, 0);	
				
    			int iAmount = _qryBillDetail.FieldByName("bill_amount").AsInteger;
			    double fExamCost = _qryBillDetail.FieldByName("bill_examcost").AsFloat;
			    double fExamCharge = _qryBillDetail.FieldByName("bill_examcharge").AsFloat;
			    ////
				_qryBillDetail.Edit();
		    	_qryBillDetail.FieldByName("bill_amount").Value = iAmount + iHisAmount - 1;
		    	_qryBillDetail.FieldByName("bill_examcharge").Value = fExamCharge / iAmount * (iAmount + iHisAmount - 1);
		    	_qryBillDetail.FieldByName("bill_examcost").Value = fExamCost / iAmount * (iAmount + iHisAmount - 1);
				_qryBillDetail.Post();
			}
		}
		////
    	_qryHisCustom.Next();
    }
	////
	_qryBillDetail.Close();
	_qryBillDetail.SQL.Text = "SELECT * FROM " + g_sBillDetail;
	_qryBillDetail.Open();
	
    return _CalcSpareMoney();
}


//---------------------------------------------------------------------------
// 删除CC_BillDetail表记录
//---------------------------------------------------------------------------
double _DeleteBillDetail()
{ 
	// 初始化变量
    String sPatientGuid = _qryStudy.FieldByName(g_sPatientIDField).AsString;
    String sVisitID = _qryBillDetail.FieldByName("bill_visitid").AsString;
	String sExamKind = _qryBillDetail.FieldByName("bill_examkind").AsString;
	String sExamName = _qryBillDetail.FieldByName("bill_examname").AsString;
	double fExamCost = _qryBillDetail.FieldByName("bill_examcost").AsFloat;
	double fExamCharge = _qryBillDetail.FieldByName("bill_examcharge").AsFloat;
	String sItemCode = _qryBillDetail.FieldByName("bill_itemcode").AsString;
	String sItemSpec = _qryBillDetail.FieldByName("bill_itemspec").AsString;
	String sItemUnit = _qryBillDetail.FieldByName("bill_itemunit").AsString;
    int iAmount = _qryBillDetail.FieldByName("bill_amount").AsInteger;
	
	// 计算记录数
    int iRecordCount = GetRecordCount(_qryBillDetail);
    
    // 计算最大号
	int iMaxItemNo = GetMaxItemNo(sPatientGuid, StrToInt(sVisitID));
    
    // 计算sRequester
    String sStudyDepartment = _qryStudy.FieldByName("study_department").AsString;
    String sRequester = GetDeptCode(sStudyDepartment);
    
    // 计算sPerformer
    String sLoginDepartment = GetConfigStr("SysLogon", "sLastDepartment");
    String sPerformer = GetDeptCode(sLoginDepartment);
    
    // 计算sOperator
    String sLoginDoctor = GetConfigStr("SysLogon", "sLastDoctorName");
    String sOperator = GetUserID(sLoginDepartment, sLoginDoctor);
    
	if (_ischarging) // 收费时删除项目
	{
		_qryBillDetail.Delete();
	}
	else // 退费时删除项目
	{		
		// 不能使用_qryCustom替代！by boost
		TADOQuery qryTempBill = new TADOQuery(nil);
		qryTempBill.ConnectionString = _opacsconnection;		
		String sBillQuery = "SELECT SUM(bill_amount) AS SUMCOUNT FROM " + g_sBillDetail;
        sBillQuery = AddWhereCondition(sBillQuery, "bill_examkind = '" + sExamKind + "'");
        sBillQuery = AddWhereCondition(sBillQuery, "bill_itemcode = '" + sItemCode + "'");
		qryTempBill.Close();
		qryTempBill.SQL.Text = sBillQuery;
		qryTempBill.Open();
		int iSumAmount = qryTempBill.FieldByName("SUMCOUNT").AsInteger;
		delete qryTempBill;
		////
		if ((iSumAmount <= 0) || (iAmount <= 0))
		{
			MessageBox("该项目不能进行退费！", "电子申请单", 1);
		}
		else
		{
			int iNewItemNo = iMaxItemNo + (iRecordCount - g_iRefundRecordCount) + 1;
			
			// 退费项目，插入一条负记录
			_qryBillDetail.Append();
			_qryBillDetail.FieldByName("bill_patientid").Value = sPatientGuid;
		    _qryBillDetail.FieldByName("bill_visitid").Value = sVisitID;
		    _qryBillDetail.FieldByName("bill_itemno").Value = iNewItemNo;
		    _qryBillDetail.FieldByName("bill_examkind").Value = sExamKind;
		    _qryBillDetail.FieldByName("bill_examname").Value = sExamName;
		    _qryBillDetail.FieldByName("bill_examcost").Value = -1 * fExamCost;
		    _qryBillDetail.FieldByName("bill_examcharge").Value = -1 * fExamCharge; 
		    _qryBillDetail.FieldByName("bill_itemcode").Value = sItemCode;
		    _qryBillDetail.FieldByName("bill_itemspec").Value = sItemSpec;
		    _qryBillDetail.FieldByName("bill_itemunit").Value = sItemUnit;
		    _qryBillDetail.FieldByName("bill_amount").Value = -1 * iAmount;
		    _qryBillDetail.FieldByName("bill_datetime").Value = Now();
		    _qryBillDetail.FieldByName("bill_requester").Value = sRequester;
		    _qryBillDetail.FieldByName("bill_performer").Value = sPerformer;
		    _qryBillDetail.FieldByName("bill_operator").Value = sOperator;
            if (_qryBillDetail.FieldByName("bill_examkind").AsString == "I")
            {
				// 以下为科室专用代码：for 放射科 材料费算到本科室 
				_qryBillDetail.FieldByName("bill_requester").Value = sPerformer;
			}
			_qryBillDetail.Post();
		}
	}

    return _CalcSpareMoney();
}

//---------------------------------------------------------------------------
// 清空CC_BillDetail表记录
//---------------------------------------------------------------------------
 double _ClearBillDetail()
{
    _qryBillDetail.First();
    while (!_qryBillDetail.Eof)
    {
    	_qryBillDetail.Delete();
    }

    return _CalcSpareMoney();
}

//---------------------------------------------------------------------------
// 提交结果到HIS数据库，1=成功，0=失败
//---------------------------------------------------------------------------
int _CommitCharging()
{
	// 初始化变量
    String sPatientGuid = _qryStudy.FieldByName(g_sPatientIDField).AsString;
    String sLoginDepartment = GetDeptCode(GetConfigStr("SysLogon", "sLastDepartment"));
    String sPerformer = GetConfigStr("SysLogon", "sLastDoctorName");
    ////
    int iReportState = _qryStudy.FieldByName("report_state").AsInteger;    
    if (iReportState >= 2)
    {
    	MessageBox("已审核病人不允许执行收费退费！", "电子申请单", 1);
        return 0;
    }
    ////
    if (!PatsInHospital(sPatientGuid))
    {
    	MessageBox("该病人已经出院！无法划价收费！" , "电子申请单", 1);
		return 0;
	}

	// 提交结果
    int iFieldCount = 0;
    String sFieldPairs[2][100]; // 源表字段 => 目标表字段 
    SetArrayItem(sFieldPairs, iFieldCount, "bill_patientid", 	"PATIENT_ID");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_visitid", 		"VISIT_ID");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemno", 		"ITEM_NO");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examkind", 	"ITEM_CLASS");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examname", 	"ITEM_NAME");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examcost", 	"COSTS");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examcharge", 	"CHARGES");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemcode", 	"ITEM_CODE");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemspec", 	"ITEM_SPEC");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemunit", 	"UNITS");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_amount", 		"AMOUNT");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_datetime", 	"BILLING_DATE_TIME");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_requester", 	"ORDERED_BY");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_performer", 	"PERFORMED_BY");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_operator", 	"OPERATOR_NO");
    ////
	String sHisQuery = "SELECT * FROM INP_BILL_DETAIL WHERE 0 > 1";
    _qryHisCustom.Close();
    _qryHisCustom.SQL.Text = sHisQuery;
    _qryHisCustom.Open();
	////
	try
	{
		BeginTrans(_qryHisCustom.Connection);
		_qryBillDetail.First();
		while (!_qryBillDetail.Eof)
		{		
			_qryHisCustom.Append();
			for (int i = 0; i < iFieldCount; i++)
			{
				if (sFieldPairs[1][i] == "")
					continue;
				if (!_qryBillDetail.FieldByName(sFieldPairs[0][i]).IsNull())
					_qryHisCustom.FieldByName(sFieldPairs[1][i]).Value =
						_qryBillDetail.FieldByName(sFieldPairs[0][i]).Value;
			}
			_qryHisCustom.Post();
			////
			_qryBillDetail.Next();
		}
		CommitTrans(_qryHisCustom.Connection);
	}
	except
	{
		RollbackTrans(_qryHisCustom.Connection);
    	MessageBox("写入HIS时发生异常！请核对后重新操作！" , "电子申请单", 1);
        return 0;
    }
    
	// 更新划价结果
    String sExamNo = _qryStudy.FieldByName("study_number0").AsString;
    String sUpdate = "";
    float fCosts = 0;
    _qryBillDetail.First();
    while (!_qryBillDetail.Eof)
    {
        fCosts = _qryBillDetail.FieldByName("bill_examcost").AsFloat;
        if (fCosts == 0)
        {
            _qryBillDetail.Next();
            continue;
        }
        sUpdate = "UPDATE EXAM_ITEMS SET COSTS = " + FloatToStr(fCosts) +
            " WHERE EXAM_NO = '" + sExamNo + "' AND EXAM_ITEM_CODE = " +
            " (SELECT CLINIC_ITEM_CODE FROM CLINIC_VS_CHARGE WHERE CHARGE_ITEM_CODE = '" +
            _qryBillDetail.FieldByName("bill_itemcode").AsString + "'";
        _qryHisCustom.Close();
        _qryHisCustom.SQL.Text = sUpdate;
        try
        {
            _qryHisCustom.ExecSQL();
        }
        except
        {
            MessageBox("更新划价记录失败！请核对后重新操作！" , "电子申请单", 1);
        }
        ////
        _qryBillDetail.Next();
    }

    // 保存修改
    // 注意：study_examname必须写在study_charge赋值之前,
    //      否则在StudyFrm的OnDataChange事件中会重置为0！
    double fStudyCost = _qryStudy.FieldByName("study_cost").AsFloat;
    double fStudyCharge = _qryStudy.FieldByName("study_charge").AsFloat;
    String sStudyExamItem = _qryStudy.FieldByName("study_examname").AsString;
    double fTotalExamCost = CalcTotalExamCost(_qryBillDetail);
    double fTotalExamCharge = CalcTotalExamCharge(_qryBillDetail);
    String sTotalExamItem = CalcTotalExamItem(_qryBillDetail);
    double fSpaceMoney = CalcSpaceMoney(sPatientGuid);
    double fResult = fSpaceMoney - (fStudyCharge + fTotalExamCharge);
    ////
    _qryStudy.Edit();
    _qryStudy.FieldByName("study_examname").Value = sStudyExamItem + " " + sTotalExamItem;
    _qryStudy.FieldByName("study_cost").Value = fStudyCost + fTotalExamCost;
    _qryStudy.FieldByName("study_charge").Value = fStudyCharge + fTotalExamCharge;
    if (fResult < 0)
    	_qryStudy.FieldByName("study_payment").Value = "欠费";
    else
    	_qryStudy.FieldByName("study_payment").Value = "已付费";
    _qryStudy.Post();

    return 1;
}

//---------------------------------------------------------------------------
// 退费操作：1	成功，0	失败
//---------------------------------------------------------------------------
int _RefundCharging()
{
	// 初始化变量
	String sPatientGuid = _qryStudy.FieldByName(g_sPatientIDField).AsString;
    int iMaxVisitID = GetMaxVisitID(sPatientGuid);
	int iMaxItemNo = GetMaxItemNo(sPatientGuid, iMaxVisitID);
	////
    int iReportState = _qryStudy.FieldByName("report_state").AsInteger;    
    if (iReportState >= 2)
    {
    	MessageBox("已审核病人不允许执行收费退费！", "电子申请单", 1);
        return 0;
    }
    ////
	if (!PatsInHospital(sPatientGuid))
    {
		MessageBox("该病人已经出院！无法退费！" , "电子申请单", 1);
		return 0;
	}

	// 提交结果
    int iFieldCount = 0;
    String sFieldPairs[2][100]; // 源表字段 => 目标表字段 
    SetArrayItem(sFieldPairs, iFieldCount, "bill_patientid", 	"PATIENT_ID");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_visitid", 		"VISIT_ID");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemno", 		"ITEM_NO");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examkind", 	"ITEM_CLASS");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examname", 	"ITEM_NAME");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examcost", 	"COSTS");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_examcharge", 	"CHARGES");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemcode", 	"ITEM_CODE");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemspec", 	"ITEM_SPEC");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_itemunit", 	"UNITS");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_amount", 		"AMOUNT");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_datetime", 	"BILLING_DATE_TIME");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_requester", 	"ORDERED_BY");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_performer", 	"PERFORMED_BY");
    SetArrayItem(sFieldPairs, iFieldCount, "bill_operator", 	"OPERATOR_NO");
    ////
    double fTotalExamCost = 0.0;
    double fTotalExamCharge = 0.0;
    String sTotalExamItem = "";
    ////
	String sHisQuery = "SELECT * FROM INP_BILL_DETAIL WHERE 0 > 1";
    _qryHisCustom.Close();
    _qryHisCustom.SQL.Text = sHisQuery;
    _qryHisCustom.Open();
	////
	try
	{
		BeginTrans(_qryHisCustom.Connection);			
		_qryBillDetail.First();
		while (!_qryBillDetail.Eof)
		{
			int iItemNo = _qryBillDetail.FieldByName("bill_itemno").AsInteger;
			int iAmount = _qryBillDetail.FieldByName("bill_amount").AsInteger;
			if ((iAmount < 0) && (iItemNo > iMaxItemNo))
			{
				_qryHisCustom.Append();
				for (int i = 0; i < iFieldCount; i++)
				{
					if (sFieldPairs[1][i] == "")
						continue;
					if (sFieldPairs[0][i] == "bill_examcost")
						fTotalExamCost = fTotalExamCost + _qryBillDetail.FieldByName("bill_examcost").AsFloat;
					if (sFieldPairs[0][i] == "bill_examcharge")
						fTotalExamCharge = fTotalExamCharge + _qryBillDetail.FieldByName("bill_examcharge").AsFloat;
					if (sFieldPairs[0][i] == "bill_examname")
						sTotalExamItem = sTotalExamItem + " " + _qryBillDetail.FieldByName("bill_examname").AsString;
					////
					if (!_qryBillDetail.FieldByName(sFieldPairs[0][i]).IsNull())
						_qryHisCustom.FieldByName(sFieldPairs[1][i]).Value =
							_qryBillDetail.FieldByName(sFieldPairs[0][i]).Value;
				}
				_qryHisCustom.Post();
			}
			////
			_qryBillDetail.Next();
		}
		CommitTrans(_qryHisCustom.Connection);		
	}
	except
	{
		RollbackTrans(_qryHisCustom.Connection);
    	MessageBox("写入HIS时发生异常！请核对后重新操作！" , "电子申请单", 1);
        return 0;
   }

    // 注意：study_examname必须写在study_charge赋值之前,
    //      否则在StudyFrm的OnDataChange事件中会重置为0！
    double fStudyCharge = _qryStudy.FieldByName("study_charge").AsFloat;
    double fStudyCost = _qryStudy.FieldByName("study_cost").AsFloat;
    String sStudyExamItem = _qryStudy.FieldByName("study_examname").AsString;
    double fSpaceMoney = CalcSpaceMoney(sPatientGuid);
    double fResult = fSpaceMoney - (fStudyCharge + fTotalExamCharge);
    ////
    _qryStudy.Edit();
    _qryStudy.FieldByName("study_examname").Value = SubtractString(sStudyExamItem, sTotalExamItem, chr(32));
    _qryStudy.FieldByName("study_cost").Value = fStudyCost + fTotalExamCost;
    _qryStudy.FieldByName("study_charge").Value = fStudyCharge + fTotalExamCharge;
    if (fResult < 0)
    	_qryStudy.FieldByName("study_payment").Value = "欠费";
    else
    	_qryStudy.FieldByName("study_payment").Value = "已付费";
    _qryStudy.Post();
    
	return 1;
}
//---------------------------------------------------------------------------

// 主程序
{
    // Nothing need to do.
}
//---------------------------------------------------------------------------
