古詩詞大全網 - 成語經典 - ERP系統單據編碼規則

ERP系統單據編碼規則

單據編碼是ERP系統中必備的功能,用於生成各種單據的流水號,常常借助於日期時間等字符來生成壹個唯壹的單據號碼。

從軟件的角度來說,就是為生成數據表的主鍵值(參考編號),從用戶的角度來說,就是給業務單據制定編碼規範。之後做到見名知意。

舉個例子:比如銷售訂單號是SO201508190001,采購訂單號碼是PO201508190001。

1 基礎單據編碼 Document serialization basic?

單據編碼主表,用於存放單據及其編碼規則。

CREATE?TABLE?[dbo].[DocumentSerialization](

[SeriesCode]?[NVARCHAR](8)?NOT?NULL,

[Description]?[NVARCHAR](40)?NOT?NULL,

[Suspended]?[NVARCHAR](1)?NULL,

[SerialLength]?[DECIMAL](2,?0)?NULL,

[PrefixLength]?[DECIMAL](2,?0)?NULL,

[Prefix]?[NVARCHAR](12)?NULL,

[NextSeqNo]?[DECIMAL](10,?0)?NULL,

[AllowOverride]?[NVARCHAR](1)?NULL,

[CreatedDate]?[DATETIME]?NULL,

[CreatedBy]?[NVARCHAR](10)?NULL,

[RevisedDate]?[DATETIME]?NULL,

[RevisedBy]?[NVARCHAR](10)?NULL,

[WithReset]?[NVARCHAR](1)?NULL,

[PrevResetDate]?[DATETIME]?NULL,

[PrefixDefault]?[NVARCHAR](12)?NULL,

CONSTRAINT?[PK_DocumentSerialization]?PRIMARY?KEY?CLUSTERED?

(

[SeriesCode]?ASC

)WITH?(PAD_INDEX?=?OFF,?STATISTICS_NORECOMPUTE?=?OFF,?IGNORE_DUP_KEY?=?OFF,?ALLOW_ROW_LOCKS?=?ON,?ALLOW_PAGE_LOCKS?=?ON)?ON?[PRIMARY]

)?ON?[PRIMARY]

GO

舉例說明,這些字段值的含義。

處理銷售訂單功能SLSOSO,它的單據編碼總長度是12,序號前綴長度是6,序號前綴規則是SO@Y@M,@Y表示兩位數的年,@M表示兩位數的月份,下壹個單據編碼流水號是4,所以當產生處理銷售訂單的單據編碼時,它是SO1508000004。

2 宏處理 Macro

有時候我們需要根據情況選擇壹種或多種序列號生成方式,在生成序號的時候彈出窗體,讓我們選擇要哪壹種前綴編碼方案,比如采購訂單的編碼規則,有時候是PO201508180001,有時候是OE201508180001,它們的前綴(Prefix)是不壹樣的。為達到這種目的,我們給DocumentSerialization增加子表。

CREATE?TABLE?[dbo].[DocumentSerializationDetail]

(

[Index]?[int]?NOT?NULL,

[SeriesCode]?[nvarchar]?(8)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NOT?NULL?,

[Prefix]?[varchar]?(12)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NOT?NULL,

[TextPattern]?[varchar]?(12)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NOT?NULL?CONSTRAINT?,

[NextSeqNo]?[decimal]?(10,?0)?NULL,

[CreatedDate]?[datetime]?NULL,

[CreatedBy]?[varchar]?(10)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NULL,

[RevisedDate]?[datetime]?NULL,

[RevisedBy]?[varchar]?(10)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NULL,

[Suspended]?[varchar]?(1)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NULL

)?ON?[PRIMARY]

GO

ALTER?TABLE?[dbo].[DocumentSerializationDetail]?ADD?CONSTRAINT?[PK_DocumentSerializationDetail]?PRIMARY?KEY?CLUSTERED?([Index],?[SeriesCode])?ON?[PRIMARY]

GO

ALTER?TABLE?[dbo].[DocumentSerializationDetail]?ADD?CONSTRAINT?[FK_DocumentSerializationDetail_DocumentSerialization]?FOREIGN?KEY?([SeriesCode])?REFERENCES?[dbo].[DocumentSerialization]?([SeriesCode])

GO

參考下面的數據例子來理解這個表的含義:

使用問號作為占位符,在運行時彈出窗體讓用戶選擇哪壹種單據編碼方案,用戶選擇PO,則生成PO201508前綴的采購訂單編碼,如用戶選擇OE,則生成OE201508前綴的采購訂單編碼。

為了加深對占位符號的理解,舉例說明以下幾種情況。

1? 前綴定義值是 ?ABC,用戶選擇XY,則返回前綴結果XYABC。?

2? 前綴定義ABC,用戶選擇XY,返回結果前墜XY_ABC,對於不多余的占位符號用下劃線替代。?

3? 前綴定義@D@M@YABC,當前日期是2015年8月19日,則生成的前綴值是150819ABC。

3 基於用戶的需要編碼方案 User-based document serialization

有時候不同的用戶有不同的單據編碼規則,我們需要依照用戶來創建編碼規則。先創建數據庫。

CREATE?TABLE?[dbo].[DocumentSerializationUser]

(

[Index]?[int]?NOT?NULL,

[SeriesCode]?[nvarchar]?(8)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NOT?NULL?,

[UserId]?nvarchar(10)?NOT?NULL?COLLATE?SQL_Latin1_General_CP1_CI_AS?NOT?NULL?,

[Prefix]?[varchar]?(12)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NOT?NULL,

[TextPattern]?[varchar]?(12)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NOT?NULL?CONSTRAINT?,

[NextSeqNo]?[decimal]?(10,?0)?NULL,

[CreatedDate]?[datetime]?NULL,

[CreatedBy]?[varchar]?(10)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NULL,

[RevisedDate]?[datetime]?NULL,

[RevisedBy]?[varchar]?(10)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NULL,

[Suspended]?[varchar]?(1)?COLLATE?SQL_Latin1_General_CP1_CI_AS?NULL

)?ON?[PRIMARY]

GO

這個表也是序號編碼DocumentSerialization的子表,主鍵增加了用戶編碼字段UserId,記錄每個用戶要編碼規則。

在系統中,優先使用基於用戶的編碼規則,其次是宏替換處理,最後才是應用基礎的編碼規則。

4 並發處理 Concurrency

當兩個並發用戶同時創建或保存壹張同樣的業務單據時,系統會返回兩個相同的單據編碼,產生了並發問題。

A 方案

打開業務功能時,立即為當前單據創建單據編碼,比如產生單據編碼SO15080004,在單據保存時,發現這張單據編碼被其它的用戶使用過,則重新產生壹個新的業務單據編碼SO15080005,如有發現此編碼仍然被占用,依此向下搜尋,直到找到可以保存的單據編碼。

這種方案的優點是總是可以保存單據,缺點是界面中看到的單據編碼,不壹定是最終保存的單據編碼。

B 方案

打開業務功能時,不產生單據編碼,只有在單據保存時才產生單據編碼。避免了單據並發沖突。

這種方案優點是沒有並發沖突,缺點是只有單據保存之後才可以看到單據編碼。

5 編碼規則程序設計 Document serialization programming

在單據保存時,調用接口產生編碼規則,參考下面的程序片段。

EcnEntity?ecn.....

if?(ecn.IsNew?&&?seriesCode?!=?string.Empty)

{

IDocumentSerializationManager?serializationManager?=ProxyInstance<IDocumentSerializationManager>();

ecn.EcnNo?=?serializationManager.GetNextSerialNo(sessionId,?seriesCode,?ecn.EcnNo,?ecn);

}

如果業務單據的實體保存時發生異常,則需要重置用戶編碼,清除產生的序號編碼。

catch

{

adapter.Rollback();

if?(ecn.IsNew?&&?string.CompareOrdinal(ecn.EcnNo,?currentRefNo)?!=?0)

{

try

{

ecn.EcnNo?=?currentRefNo;

serializationManager.ResetNextSequenceNo(seriesCode);

}

catch

{

}

}

throw;

}

6 固定編碼規則? Fixed document serialization

以上實現了基於流水號的單據編碼規則,如果單據的編碼規則相對固定,則以上方法行不通。請先閱讀下面的需求說明:

接到客戶訂單,訂立合同編號:HT201508003;接著做合同評審,產生壹個合同評審單號PS201508003;合同評審通過以後,再到ERP系統中做銷售單,銷售單號是XSD201508003;如果壹個合同分三個銷售訂單下單,則會分別產生XSD201508003-01,XSD201508003-02,XSD201508003-03 三個銷售訂單號。繼續為銷售訂單發貨,銷售訂單XSD201508003所產生的發貨單號應該是XSFH201508003,如果銷售訂單XSD201508003分三次發貨,則依次產生的三張銷售發貨單號是XSFH201508003-01,XSFH201508003-02,XSFH201508003-03。

單據編號201508003從銷售合同到銷售發貨都是同壹個單據號,只是編碼前綴不同。

這種編碼方案要求壹個單據號碼貫穿整個流程,單據編號從起始點業務單據傳遞到最終業務單據,僅僅是前綴不同。

要實現這種固定格式的單據編碼,需要對流轉的每個單據進行編程處理,業務單據也應該有固定的下推流程,做不到通用性,但是優點是很明顯的,壹個號碼貫穿整個業務單據,非常清晰明了。

參考:博客園