The documents of ERP system have standard function, the documents here can be translated into bill,document,entry and have similar tool-bar operation interface. By designing reusable base classes, subclasses only need to inherit the base class form to complete the design of the document function. First look at the standard Sales contract document interface:
This article through the Sales Contract document function, in turn explains the programming key points, for the reference.
1 Add Insert
Form has two states, one is the editing state, the other is the data browsing state, the difference is that the editing state of the form data is modified (dirty), when the form closes, you need to save the data. Click the new (Insert) button on the toolbar to enter the editing state. The new state requires setting a default value for the document that the form is editing. Generally we set the default value in the entity mapping file, refer to the following example code:
public partial Class salescontractentity{protected override void oninitialized () {base . OnInitialized (); //Assign default value for new entity if (fields.state = = entitystate.new) { #region defaultvalue //__llb Lgenpro_user_code_region_start defaultvalue this . fields[(int ) salescontractfieldindex.closed]. CurrentValue = false ; //__llblgenpro_user_code_region_end #endregion } } }
You can also consider setting default values in the form. When you encounter a scenario where two functions correspond to the same entity type, you need to initialize the values in the interface as needed, referring to the program fragment below.
protected Override EntityBase2 Add () { base. Add (); This New Inventorymovemententity (); this. _inventorymovement.trantype = GetStringValue (inventorytransactiontype.movement); return this. _inventorymovement;}
2 Saving Save
The form base class detects that the value of the control in the interface has been modified, the form state becomes an edit state, and the Save button is clicked to execute the Save method. The main content of the Save method is to update the control value that the data source control (BindingSource) binds to the entity it maps to, and then call the form save method to save the entity.
protected Override EntityBase2 Save (EntityBase2 entitytosave, entitycollection entitiestodelete) { salescontractentity Salescontractentity = (salescontractentity) entitytosave; This this. _salescontractentitymanager.savesalescontract (salescontractentity, Entitiestodelete, SeriesCode); return this. _salescontractentity;}
Entitytosave is the entity type that the data source control binds to, and after the save is complete, the value is bound to the data source control again.
3 deleting Delete
When the form is only in the browse state, the Delete button can be clicked, the content of the Delete button is the entity that gets the form data source control bound, and the form is called the Delete method.
protected override void Delete (EntityBase2 entitytodelete) {base . Delete (Entitytodelete); Salescontractentity salescontractentity = (salescontractentity) entitytodelete; this . _salescontractentitymanager.deletesalescontract (salescontractentity);}
Any operation on the entity will run the entity validation type, for example, when saving, you need to verify that the primary key value has been saved, refer to the following code.
Public Override void Validateentitybeforesave (Ientitycore involvedentity) { base. Validateentitybeforesave (involvedentity); Salescontractentity salescontract = (salescontractentity) involvedentity;
if(string. IsNullOrEmpty (Salescontract.contractno))Throw NewEntityvalidationexception ("Contract No." is required ");if(string. IsNullOrEmpty (Salescontract.customerno))Throw NewEntityvalidationexception ("Customer No." is required ");if(salescontract.isnew) {Isalescontractmanager Salescontractmanager = Createproxyinstance<isalescontractmanag Er> ();if(Salescontractmanager.issalescontractexist (Salescontract.contractno))Throw NewRecordduplicatedexception (Salescontract.contractno,"Cotract No." is already used "); }}
4 Copy Clone
The form supports two methods of copying, copying the currently loaded values, and copying the values of other objects. After the object value is copied, you need to reset the primary key value of the new object so that it is empty or a default value for the user to modify. Copying the values of other objects requires a Popup object selection form. Both types of replication need to be aware that resetting the object initialization defaults after the copy is complete. Because a deep copy is used for replication, there is no running object initialization value.
protected Override ObjectClone (dictionary<string,string> Refno) {Base. Clone (REFNO);stringRECEIPTREFNO; Refno.trygetvalue ("Contractno", outRECEIPTREFNO);if(string. IsNullOrEmpty (RECEIPTREFNO)) {using(Ilookupform lookup = Getlookupform ("Salescontractlookup")) {if(! allowviewalltransaction) lookup. Predicatebucket =NewRelationpredicatebucket (Salescontractfields.createdby = = Shared.CurrentUser.UserId); Lookup. Setcurrentvalue (CURRENTREFNO);if(Lookup. ShowDialog ()! = DialogResult.OK)
return null; RECEIPTREFNO = lookup. Getfirstselectionvalue (); } } if (! string. IsNullOrEmpty (RECEIPTREFNO)) {This . _ Salescontractentitymanager.clonesalescontract (RECEIPTREFNO); return this. _salescontractentity; } return null;
}
Note that these methods are all present in override overrides and are called by the base class. Each method runs in the BackgroundWorker thread of the spool program, so the interface control cannot be manipulated.
5 Records Browse Record Navigator
Mainly used for the first four buttons of the toolbar, respectively, corresponding to the initial data, the previous data, the next data, the last data. Toolbar browsing needs to set the Navigatebindingsource property of the form, pass in a blank BindingSource control or a BindingSource control that loads all the data on the page, and the toolbar browse method overrides the following program fragment.
protected override void Initnavigator (Initnavigatorargs args) {base . Initnavigator (args); Args. Sortexpression.add (Salescontractfields.contractno | sortoperator.ascending); Args. PREDICATEBUCKET.PREDICATEEXPRESSION.ADD (salescontractfields.closed = = false );}
6 Recording posting record post
Mainly used for business document posting logic, the base class method is an empty method, different business documents have different logical definitions, there is no reusable code.
protected override void Post (EntityBase2 entitytopost) {base . Post (Entitytopost); Salescontractentity resignentity = entitytopost as salescontractentity; _salescontractentitymanager.postsalescontract (resignentity); }
The posting here can be understood as confirmation, approval, non-change of meaning. In some systems called for review, Audit.
7 Printing Print
In general, the Design view binds the Crystal Report file corresponding to the current form and the parameters to be passed in. You can also pass in numeric values by overriding the printing method.
protected Override void Print (ref dictionary<stringrefref list<parameterfield> Parameterfields) { base. Print (refrefref parameterfields);}
Override methods are often used to dynamically specify a report file, or dynamic parameter values. It is not recommended to write in code like this, which results in the need to recompile and distribute the program every time, it is recommended to make the formula in the Crystal Report, only need to copy the file when distributing.
Parsing of large. NET ERP System Document standards (add, modify, delete, copy, print) functional programming