#ifndef H_DATA_DOC
/// 数据文档类定义
#define H_DATA_DOC
#include "i_dd.h"
#include "i_biz.h"
#include "i_data_doc.h"
#include "auto_pointer.h"
#include "i_log.h"
#include "xxml.h"
#include "i_dataimporter.h"
struct CBillDocDetail {
unsigned short id_; ///< 从表文档元素的ID,第1个从表对应id=1,依次类推
unsigned long record_count_; ///< 记录数
unsigned short detail_field_count_;
XERCES_CPP_NAMESPACE::DOMElement *cur_record_; ///< 当前记录对应的元素
public:
CBillDocDetail():id_(0),record_count_(0),detail_field_count_(0) {
}
virtual int NewRecord() = 0;
virtual int OutputRecord(CRecordset *prs) = 0;
};
struct CUMXBillDocDetail : public CBillDocDetail {
CRowset *rs_;
bool has_col_info_;///< 是否已有行集信息
public:
CUMXBillDocDetail(unsigned short id):rs_(0),has_col_info_(false) {
id_ = id;
}
int NewRecord();
int OutputRecord(CRecordset *prs);
};
class CXMLDataDoc;
struct CXMLBillDocDetail : public CBillDocDetail{
DOMElement *detail_;
DOMElement *detail_field_count_elem_; ///< 从表字段数元素
DOMElement *record_count_elem_;
DOMElement *records_; ///< records元素
CXMLDataDoc *data_doc_;
CXMLBillDocDetail(unsigned short id):detail_(0),detail_field_count_elem_(0),record_count_elem_(0),records_(0),data_doc_(0){
id_ = id;
}
int NewRecord();
int OutputRecord(CRecordset *prs);
};
struct CBillDocAttribute {
string name_;
string value_;
};
/// 数据文档基类
class CDataDoc : public IDataDoc {
protected:
string vender_id_; ///< 商家编号
string file_name_; ///< 输出的文件名(带完整路径)
CQQ_ORGID orgid_;
short version_; ///< 版本
ISheetTypeInfo *sti_; ///< 单据类型信息
CQQ_RULEID rule_id_; ///< 生成此数据的抽取规则ID
CQQ_INTFID intf_id_; ///< 符合的接口ID
unsigned long ext_prop_; ///< 扩展属性
CAutoVector<CBillDocAttribute*> props_; ///< 扩展属性
IDataImporter *importer_;
public:
unsigned short master_field_count_;
CAutoVector<CBillDocDetail*> details_;///< 对于单表,details_包含表的记录信息,对于主从表,则包含所有明细的内容
static INative_Logger_Base *log_; ///< 日志输出对象
static IBiz *ibiz_;
public:
CDataDoc():orgid_(0),version_(1),sti_(0),rule_id_(0),intf_id_(0),ext_prop_(0) {
}
virtual ~CDataDoc() {
}
void SetOrgID(CQQ_ORGID orgid) { orgid_ = orgid; }
CQQ_ORGID GetOrgID() const { return orgid_; }
void SetVersion(short version) { version_ = version; }
short GetVersion() const { return version_; }
void SetRuleID(CQQ_RULEID rule_id) { rule_id_ = rule_id; }
CQQ_RULEID GetRuleID() const { return rule_id_; }
void SetIntfID(CQQ_INTFID intf_id) { intf_id_ = intf_id; }
CQQ_INTFID GetIntfID() const { return intf_id_; }
void SetVenderID(const char *vender_id) { vender_id_ = vender_id; }
const char* GetVenderID() const { return vender_id_.c_str(); }
void SetFileName(const char *fn) { file_name_ = fn; }
const char* GetFileName() const { return file_name_.c_str();}
void SetSheetType(ISheetTypeInfo *sti) { sti_ = sti; }
ISheetTypeInfo* GetSheetType() const { return sti_; }
void SetProp(unsigned long prop) { ext_prop_ = prop; }
unsigned long GetProp() const { return ext_prop_; }
void AddAttribute(const char *name,const char *value);
unsigned short GetAttributesCount();
CBillDocAttribute* GetAttribute(unsigned short index);
void ClearAttributes();
void SetImporter(IDataImporter *importer) { importer_ = importer;}
virtual CBillDocDetail* NewDetail(unsigned short id) = 0;
CBillDocDetail* GetDetail(unsigned short id) {
return details_[id-1]; ///< 目前id从1开始顺序压入details_的.
}
virtual int Create() = 0; ///< 创建文档
virtual int PreOutput() { return 0; }
virtual int Output(const char *fn) { file_name_ = fn; return 0;} ///< 输出文档
virtual int OutputMasterRecord(CRecordset *prs) = 0;
CMsg* CreateDataMsg();
virtual unsigned int Type() const = 0; ///< 文件格式类型
virtual const char* FileExtName() const = 0; ///< 文件扩展名
virtual int Parse(const char *file_name) = 0; ///< 解析文件生成文档对象
virtual int Import(CMsg **ppMsg) = 0; /// 根据导入器指定的接口生成数据对象的UMX消息(如单据信息)
void Release() { delete this;}
};
/// UMX数据文档
class CUMXDataDoc : public CDataDoc {
CMsg *doc_;
CUMXBillDocDetail *master_data_;
public:
CUMXDataDoc():doc_(0) {
}
~CUMXDataDoc() {
if (doc_)
doc_->Release();
}
int Create(); ///< 创建文档
CBillDocDetail* NewDetail(unsigned short id);
int Output(const char *fn); ///< 输出文档
int OutputMasterRecord(CRecordset *prs);
unsigned int Type() const { return 2; }
const char* FileExtName() const { return "umx";}
int Parse(const char *file_name);
int Import(CMsg **ppMsg);
};
/// XML数据文档类
class CXMLDataDoc : public CDataDoc {
int GetMasterData(DOMElement *billElem,CMsg *msg,short version);
public:
XERCES_CPP_NAMESPACE::DOMDocument* doc_;
DOMElement *bills_; ///< bills元素
DOMElement *bill_;
DOMElement *master_field_count_elem_; ///< 主表字段数元素.实际上是根据master_field_count_elem_是否为NULL来判定是单表还是主从表的
bool delete_doc_; ///< 是否自动删除doc_对象,执行Parse生成的doc_需要由导入器释放
public:
CXMLDataDoc():doc_(0) {
delete_doc_ = true;
master_field_count_elem_ = 0;
}
~CXMLDataDoc() {
if (delete_doc_&&doc_)
doc_->release();
}
CBillDocDetail* NewDetail(unsigned short id);
int OutputMasterRecord(CRecordset *prs); ///< 输出主表记录(直接在bill元素下输出)
int Create();
int Output(const char *fn);
int PreOutput(); ///< 补充完整的Document信息,可用来输出到文件或者直接处理
unsigned int Type() const { return 1; }
const char* FileExtName() const { return "xml";}
int Parse(const char *file_name);
int Import(CMsg **ppMsg);
};
typedef CDataDoc CBillDoc;
#endif