Use the Winbooks.Apis.Services

Introduction


Apis is the client library which helps .NET developer access Winbooks API in fast and easy way.

User could download Apis library in this  ApisLibrary.rar  

This library is written in C# and compatible with .NET framework 4.0 or later.

All examples of codes are included in  Winbooks.Apis.Demo.rar  

Note: Current version of ApisLibrary and Demo project is now associated with WOW version 2.2.0

For client using old version, we recommend you to make an update for getting the best result.

The packed file


When you extract the packed file, you will find the 5 following assemblies:

    • Winbooks.Apis.Services
    • Winbooks.Serializer
    • Winbooks.TORM.OM
    • Winbooks.TORM.DAL
    • Newtonsoft.Json.dll

Winbooks.Apis.Service is the main assembly. It's handling the connection to the Winbooks on Web API, the authentication and the interaction with data. 

Winbooks.Serializer: As we know, in the communication between client and server API, data is always in JSON or XML format. But what a .NET developer really needs is an object, so this assembly will convert the JSON result from API to .NET object.

Winbooks.TORM.OM and Winbooks.TORM.DAL: 2 assemblies including the object model and the data access layer of WinBooks on Web.

Setup


There are a few setup steps you need to complete before you can use this library:

Authentication


It is important to understand the basics of how API authentication is handled. Every request going to the Winbooks on Web API needs to be authorised through an access token. To get this access token, the developer needs to authenticate themselves. And because the access token is life-limited, we also need to handle refresh tokens for getting a new access token every time it expires. This looks like a lot of jobs need to be handled here. But with Apis library, we just need to create one simple object UserCredential, and UserCredential will handle all this work for you.

UserCridential has 3 paramerters: 

  • url: is the Winbooks API host you receive in email 
  • email: an email by which you receive exchange token
  • exchange token: is created after you finish this Getting Exchange Token
Create an UserCridential instance
1
2
//Create User UserCredential : api host, email, exchange token
UserCredential userCredential = new UserCredential( "https://tst-rapi.winbooksonweb.vn" , "anhthu@winbooks.be" , "WYnuU46ejup8a1Ar2hAbApiOauuRq4H/h3jpvSpwn5om8+vrKF/JJvDq3vPP08Q7heD6RdHVAwQaNoWsbBhkTU5KEjL/9hw84lTd6ldpO7yUBV0kaVrXkkx1Zv1w/3j1m5FK+MTga2MM8scrh9G4EW1MQrNGQmNLknG8WRcFjV9I+edZeYlbHRjldVaWxtd7" );

Entity Services 


A user could have access to many folders in Winbooks on Web application. Therefore, the client needs to specify which folder he wants to access. In Apis, each folder-access is presented by an EntitiesServices object. This object will handle all work like query, insert, update or delete data in this folder.

Parameters

EntitiesServices has 2 parameters:

  • UserCredential: the UserCredential is created above
  • Folder Code: Code of folder that the client wants to access 
Create an EntitiesServices
1
2
// this create an access to folder HOFMAN
  EntitiesServices folderHOFMAN = new EntitiesServices(userCredential, "HOFMAN" );

Setting 

In entity services, setting is presented by object BaseEntitySetting with 4 properties: 

  • GetEntityLevel: the level for getting data
  • SendEntityLevel: the level for sending data to API
  • IsValidate: indicate Apis should validate data before sending data to API
  • IsShowId: indicate client wants to have Id info or not

Method 

GET

  • GetByCode: return object unique by code
  • GetById: return object unique by id
  • GetByFilter: return first object matched given condition
  • GetFilterAll: return all object matched given condition
  • GetAll: return all objects in current folder

INSERT

  • Insert: insert new object
  • InsertCollection: insert a list of new object

UPDATE

  • UpdateByCode: update object unique by code
  • UpdateById: update object unique by id
  • UpdateCollection: update a collection of object

DELETE

  • DeleteByCode: delete object unique by code
  • DeleteById: delete object unique by Id
  • DeleteByFilter: delete all objects matched the given condition

Entity Level

As you can see, in Customer, we have many sub-entities like Third, Vat, Category and Template inside. What if we need info in the sub entity? We could assign Customer as level 1, and sub entities like Third, Vat, Template as level 2. For doing this, we have 2 ways:

Manually retrieve sub entities
1
2
3
4
//Getting info of Customer COSMOSHOP with 2 level
Customer cosmoCustomerWith3Level = folderPARFIWEB.GetByCode<Customer>( "COSMOSHOP" , 2);
//Now you have info third of COSMOSHOP Customer
Third thirdOfCosmoCustomer = cosmoCustomerWith3Level.Third;
Automatically retrieve sub entities using BaseEntitySetting
1
2
3
4
5
6
7
8
9
10
//Using BaseEntitySetting
BaseEntitySetting setting = new BaseEntitySetting();
setting.SendEntityLevel = 2;
setting.GetEntityLevel = 2;
setting.IsShowId = false ;
setting.IsValidate = true ;
//Getting info of Customer COSMOSHOP with setting
Customer cosmoCustomerWithBaseEntitySetting = folderPARFIWEB.GetByCode<Customer>( "COSMOSHOP" , setting);
//Info Third of COSMOSHOP Customer
Third third = cosmoCustomerWithBaseEntitySetting.Third;

Customer


After creating an EntitiesServices to access folder, now we can begin to work with data. Let's take a specific example for Customer object.

1. Retrieve one Customer

Get by Code


One Customer is unique by their Code. To get info of one Customer,  we will use method GetByCode() with parameter is Customer Code and object type is Customer 
Retrieve Customer with Code "COSMOSHOP"
1
2
//Getting info of customer COSMOSHOP
Customer cosmoCustomer = folderPARFIWEB.GetByCode<Customer>( "COSMOSHOP" );

Just one simple line of code and you will have information of Customer "COSMOSHOP". 

Get by Id

In case client doesn't have Customer "Code" but he knows the Customer "Id", then we could use method GetById()  with parameter is Customer Id and object type is Customer

Get Customer by Id
1
2
//Getting info of Customer which have Id
Customer CustomerWithId = folderPARFIWEB.GetById<Customer>( "79A2E56E-2BE7-4216-BA75-9F9400FB45BD" );

Get Filter 

What if we don't know either Customer "Code" or "Id", but we want to find customer based on other information like Name is "Cosmo British Shop"? So we could use method GetFilter().

This method has one parameter which is a Critera object (Criteria is presented for how conditions will be described) and will return the first result that matches the condition.  

Example explanation: As you can see, Customer has a relationship with object Third by holding Third_Id. The Customer's name is the property "Name" of Third. So we want to find Customer with the name "Cosmo British Shop", this means we want to find a Customer whose Third's name is "Cosmo British Shop"

Create a condition
1
2
3
4
5
6
//Create Condition : find Customer which have Third and Third name is "Cosmo British Shop"
ICriteria criteria = new CustomerDAO().CreateCriteria();
criteria.CreateAlias( "th" , typeof (Third), Third.Names.Id, Customer.Names.Third_Id);
criteria.Add(Condition.Eq( "th." + Third.Names.Name, "Cosmo British Shop" ));
//get customer by filter
Customer customerByFilter = folderPARFIWEB.GetFilter<Customer>(criteria);

2. Retrieve a list of Customers

Now we work with multiple data. It's basically the same as single data. We have 2 functions:

  • GetAll(): this method is for getting all Customers in current folder 
  • GetFilterAll(): this method is for getting all Customers which match the filter condition
     
  •  Get All 

With large amounts of data, this method will take time to process

Get all Customers in folder
1
2
//get all Customer in folder PARFIWEB
IList<Customer> allCustomer = folderPARFIWEB.GetAll<Customer>();
  • Get Filter All

This function is the same as method (GetFilter) instead of returning the first result, it will return all results which match the condition

So we want to find 10 customers which have VatCountry Code is "BE". This means we want to find 10 Customers whose Third's Country Code is "BE" 

Get Filter All
1
2
3
4
5
6
7
8
9
10
11
//Create condition : get top 10 customer with country is BE
ICriteria criteriaFilterAll = new CustomerDAO().CreateCriteria();
criteriaFilterAll.CreateAlias( "th" , typeof (Third), Third.Names.Id, Customer.Names.Third_Id);
criteriaFilterAll.CreateAlias(JoinType.InnerJoin, "th" , "vatCountry" ,
                 typeof (Winbooks.TORM.OM.Country), Winbooks.TORM.OM.Country.Names.Id,
                 Third.Names.VatCountry_Id);
criteriaFilterAll.Add(Condition.Eq( "vatCountry." + Country.Names.Code, "BE" ));
criteriaFilterAll.SetFirstResult(0);
criteriaFilterAll.SetMaxResults(10);
// Get Filter All
IList<Customer> lstCustomerBE = folderPARFIWEB.GetFilterAll<Customer>(criteriaFilterAll);

3. Update one Customer

Update by Code

Update Customer by Code
1
2
3
4
5
//GETTING INFO OF CUSTOMER COSMOSHOP
Customer cosmoCustomer = folderPARFIWEB.GetByCode<Customer>( "COSMOSHOP" );
//Update Memo of Customer
cosmoCustomer.Memo = "this is the memo for customer Cosmo" ;
folderPARFIWEB.UpdateByCode<Customer>(cosmoCustomer, 1);

 

Update b y Id

Update Customer by Id
1
2
3
4
5
//GETTING INFO OF CUSTOMER WHICH HAVE ID
Customer customerWithId = folderPARFIWEB.GetById<Customer>( "79A2E56E-2BE7-4216-BA75-9F9400FB45BD" );
//Update Memo of Customer
customerWithId.Memo = "this is the memo update customer by id" ;
folderPARFIWEB.UpdateById<Customer>(cosmoCustomer, 1);

 

  • Update Customer with sub cascade entities is modified

Some sub entities are supported cascade. For example, in customer, Third is a cascade save-update property. This means when you modify/insert new Third property in customer and send back to API, both Customer table and Third table are also updated/inserted. As we mentioned before, Customer is level 1 so Third is level 2 . When modifying Third, you have to put parameter entityLevel  as 2 in method  UpdateByCode  or  UpdateById  (If you already declared setting before, then there is no need to add more parameters)

 

Update Customer with Third
1
2
3
4
5
6
7
//GETTING INFO OF CUSTOMER COSMOSHOP WITH 2 LEVEL
Customer cosmoCustomerWith3Level = folderPARFIWEB.GetByCode<Customer>( "COSMOSHOP" , 2, true );
//MODIFY MEMO AND THIRD
cosmoCustomerWith3Level.Memo = "this customer is modified with sub entities inside" ;
cosmoCustomerWith3Level.Third.WebSite = "www.cosmoshop.com" ;
//setting level info for sending to api
folderPARFIWEB.UpdateById<Customer>(cosmoCustomerWith3Level, 2);

 

cascade in customer

Beside the cascade save-update, we also have 

  • delete-orphan: when the object is deleted, delete all the objects in the association. In addition to that, when an object is removed from the association and not associated with another object (orphaned), also delete it.
  •   all-delete-orphan: when an object is saved/updated/deleted, check the association and save/update/delete all the objects found. In additional to that, when an object is removed from the association and not associated with another object (orphaned), also delete it.

In customer, we have the following properties in cascade

  • Third: save-update
  • TotalBalancesCurrency: delete-orphan
  • TotalBalances: delete-orphan
  • BalancesCurrency: delete-orphan
  • Balances: delete-orphan
  • PricesDiscounts: all-delete-orphan

Another way to update Customer - Update Customer by inserting request

Besides 2 methods UpdateByCode and UpdateById, we could use method inserting for updating an existing customer. Just create a new customer which has the same code or id as the existing customer, edit property and send back to API.
By checking existing Code or Id, API will know this insert-request is actually an update-request
**When sending back to api, client could skip the validation step by setting IsValidate = false. We don't need to validate mandatory fields in here, because this GLAccount already exists and all mandatory fields already exist in database too.

 

Another way for updating Customer
1
2
3
4
5
6
7
8
9
//Another way to update customer
Customer newCustomerHaveSameCode = new Customer();
// set customer Code is an existing customer Code
newCustomerHaveSameCode.Code = "COSMOSHOP" ;
newCustomerHaveSameCode.Vat = new VatAccount();
// set Vat.Code is an existing Vat => so Rest API will update vat of Customer is the existing Vat have code "PST6"
newCustomerHaveSameCode.Vat.Code = "PST6" ;
// because we intend to update existing customer not insert, all mandatory fields is already existed in server => so in client, we skip validation step by setting isValidated = false
folderPARFIWEB.Insert<Customer>(newCustomerHaveSameCode, 2, false );

 

4. Update a list of Customers

With collection, we have the same rules like single  one. Method  UpdateCollection() have input parameter as a list of Customers

Insert list of Customers
1
2
3
4
5
6
7
///Modify a list of Customer
foreach (var customer in lstCustomerBE)
{
     customer.Third.WebSite = "www." + customer.Third.Code.ToLower().Trim( ' ' ) + ".com" ;
}
//setting level info for sending to api
folderPARFIWEB.UpdateCollection(lstCustomerBE, 2);

 

5. Add one Customer

Without the sub entities

When inserting a new Customer, we need to remember to fill all mandatory fields. With setting IsValidate, before sending request, Apis will check all mandatory fields to see if they are presented or not. This is a necessary step because we don't want to waste time sending requests when surely that request will fail .
But in some scenarios, if client already checks and makes sure that the data is good, it is fine to skip this validation step by setting IsValidate = false
In Customer we have 3 mandatory fields: Third_Id, Code, MemoType. This means when creating a new customer, these fields must have values

Insert without sub entities
1
2
3
4
5
6
7
8
9
10
11
12
//create sinGLe customer
Customer newCustomer = new Customer();
newCustomer.MemoType = MemoType.Green;
newCustomer.Code = "ALICE" ;
newCustomer.Memo = "this memo is for customer Alice Wilder" ;
// create mandatory object
newCustomer.Third = new Third();
newCustomer.Third.Code = "ALICE" ;
newCustomer.Third.Name = "Alice Wilder" ;
newCustomer.Third.WebSite = "www.alice-wilder.com" ;
// insert new customer to folder PARFIWEB
bool isInsertSuccess = folderPARFIWEB.Insert<Customer>(newCustomer, 2);

Always remember to set entityLevel parameter equal to level data you want to send. If not, Apis will take the value of BaseSetting. If BaseSetting has never been set before, default value is 1

With the sub entities created at the same request

PriceDiscounts is a cascade save-update property in Customer. This means when we insert a new Customer with PriceDiscounts inside, API will also insert all values in PriceDiscounts

Create with sub entity
// Create Customer with sub entities Kylie Minogue
Customer customerWithSubEntity = new Customer();
customerWithSubEntity.Code = "KYLIE" ;
customerWithSubEntity.MemoType = MemoType.Green;
customerWithSubEntity.Memo = "this memo is for customer Kylie Minogue" ;
//create mandatory object
customerWithSubEntity.Third = new Third();
customerWithSubEntity.Third.Code = "KYLIE" ;
customerWithSubEntity.Third.Name = "Kylie Minogue" ;
customerWithSubEntity.Third.WebSite = "www.kylie-minogue.com" ;
// create sub entity
customerWithSubEntity.PriceDiscounts = new List<CustomerPriceDiscount>();
//Create PriceDiscount with Item 008
CustomerPriceDiscount customerPriceDiscount = new CustomerPriceDiscount();
customerPriceDiscount.Customer = customerWithSubEntity;
customerPriceDiscount.Item = new Item();
customerPriceDiscount.Item.Code = "CBURT" ;
customerPriceDiscount.Item.Name = "CBURT" ;
customerPriceDiscount.Item.StockManagementType = StockManagementType.Batch;
customerPriceDiscount.Item.StockValuationMethod = StockValuationMethod.FIFO;
customerPriceDiscount.Item.CoefSale2StockQuantity = 0;
customerWithSubEntity.PriceDiscounts.Add(customerPriceDiscount);
folderPARFIWEB.Insert<Customer>(customerWithSubEntity, 3);

Add a second contact to the Customer

 

Insert second Contact
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//adding second contact to customer
Customer addingSecondContact = new Customer();
addingSecondContact.Code = "KYLIE" ;
addingSecondContact.Third = new Third();
addingSecondContact.Third.Code = "KYLIE" ;
addingSecondContact.Third.Contacts = new List<Third_Contact>();
Third_Contact thirdContact = new Third_Contact();
thirdContact.Third = new Third();
thirdContact.Third.Code = "KYLIE" ;
thirdContact.Contact = new Contact();
thirdContact.Contact.EmailAddresses = new List<EmailAddress>();
thirdContact.Contact.EmailAddresses.Add( new EmailAddress( "kylie_minogue@gmail.com" ));
thirdContact.Contact.MemoType = MemoType.Green;
thirdContact.Contact.PhoneNumbers = new List<PhoneNumber>();
thirdContact.Contact.PhoneNumbers.Add( new PhoneNumber( "+016 256 992 4556" ));
thirdContact.Contact.FirstName = "Kylie" ;
thirdContact.Contact.LastName = "Minogue" ;
thirdContact.Contact.EmailAddressOther = "kylie_minogue@hotmail.com" ;
thirdContact.Address = new Address();
thirdContact.Address.Address1 = "152 geminova" ;
thirdContact.Address.Address1 = "258 hotungmau tphcm" ;
addingSecondContact.Third.Contacts.Add(thirdContact);
folderPARFIWEB.Insert<Customer>(addingSecondContact, 5, false );

6. Add a list of Customers

To insert a list of customer, use method InsertCollection();

Insert a list of Customers
// Create a list of customer
List< string > customerNames = new List< string >() { "Adam" , "Miranda" , "Jordin" , "Sparks" };
List<Customer> lstNewCustomers = new List<Customer>();
foreach (var customerName in customerNames)
{
     Customer cust = new Customer();
     cust.Code = customerName.Trim( ' ' ).ToUpper();
     cust.MemoType = MemoType.Green;
     cust.Memo = "this is the memo of " + customerName;
     cust.Third = new Third();
     cust.Third.Name = customerName;
     cust.Third.Code = customerName.Trim( ' ' ).ToUpper();
     cust.Third.WebSite = "www." + customerName.Trim( ' ' ).ToLower();
     lstNewCustomers.Add(cust);
}
// Insert a list of Customer
folderPARFIWEB.InsertCollection(lstNewCustomers, 2);

7. Delete one Customer

Delete by Code

To delete a Customer with Code, just put the Customer Code as parameter in method DeleteByCode();

Delete Customer by Code
1
2
//Delete a customer by code
folderPARFIWEB.DeleteByCode<Customer>( "ADAM" );

Delete by Id

If the Customer Id is known instead of the Customer Code, we can use method DeleteById()

Delete Customer by Id
1
2
//Delete a customer by Id
folderHOFMAN.DeleteById<Customer>( "D48ADC06-6ACB-4D4D-AE88-98690A29E0AE" );

8. Delete a list of Customers

 

DeleteFilter(): delete all Customers which match the given condition

Delete a list Customers
1
2
3
4
5
//delete a list customer by filter
object [] arrayCustomerCode = new string [] { "ADAM" , "MIRANDA" , "Jordin" , "SPARKS" };
ICriteria filterDelete = new CustomerDAO().CreateCriteria();
filterDelete.Add(Condition.In(Customer.Names.Code, arrayCustomerCode));
folderPARFIWEB.DeleteFilter<Customer>(filterDelete);

 

9. Retrieve the balance of one Customer 

 

We have a Customer, and now we want to find all CustomerBalance. This means we want to filter all CustomerBalance to find which one has the Customer.Code as our Customer Code

Retrieve CustomerBalance of a Customer
1
2
3
4
5
6
// get CustomerBalance of a customer
var balanceFilterCriteria = new CustomerBalanceDAO().CreateCriteria();
balanceFilterCriteria.CreateAlias( "customer" , typeof (Customer), CustomerBalance.Names.Id,
                 CustomerBalance.Names.Parent_Id);
balanceFilterCriteria.Add(Condition.Eq( "customer." + Customer.Names.Code, "CETIC" ));
var lstCustomerBalance = folderPARFIWEB.GetFilterAll<CustomerBalance>(balanceFilterCriteria, 1);

10. Retrieve the balance of a list of Customers

Now we have a list of Customers, and we want to get all CustomerBalances of these. This means we want to filter all CustomerBalances to find which has the same Code as the ones in our list of Customers

Retrieve balance of list Customers
1
2
3
4
5
6
7
// get CustomerBalance of a list of Customer
var balanceFilterCriteria2 = new CustomerBalanceDAO().CreateCriteria();
balanceFilterCriteria2.CreateAlias( "customer" , typeof (Customer), CustomerBalance.Names.Id,
                 CustomerBalance.Names.Parent_Id);
balanceFilterCriteria2.Add(Condition.In( "customer." + Customer.Names.Code, new string [] { "COMASA" , "BYHA" , "CARKATH" }));
// we should set entityLevel is 2, so now we will know which customer balance belong to which customer by object Customer inside
var lstCustomerBalanceOfListCustomer = folderPARFIWEB.GetFilterAll<CustomerBalance>(balanceFilterCriteria2, 2);

GLAccount ( general account )


1. Retrieve one GLAccount

Get by Code

An GLAccount is unique. For getting one specific GLAccount, we could use method GetByCode() with parameter as GLAccount's Code

Get GLAccount by Code
1
2
3
// Get By Code
// By setting parameter isShowId = false, the result return will not include property Id, just the code
GLAccount GLaccountByCode = folderPARIWEB.GetByCode<GLAccount>( "284000" , false );

Get by Id

Beside "Code", Id is also a unique value to identify GLAccount. We could use method  GetById() with parameter as GLAccount's Id

Get GLAccount by Id
1
2
3
4
//Get By Id
//By setting parameter isShowId = true, the result return with Id inside
folderPARFIWEB.Setting.GetEntityLevel = 2;
GLAccount GLAccountById = folderPARFIWEB.GetById<GLAccount>( "74EE6FE6-1F37-44C3-853F-9F9400B4C66C" , true );
  • Get by Filter

    Return the first GLAccount which matches the given condition; result is null if there's no GLAccount matching the condition

Get GLAccount by filter
1
2
3
4
5
// Get By filter : find GLAccount has  name 'Capital Souscrit Ou Capital Personnel'
ICriteria GLAccoutCritetia = new GLAccountDAO().CreateCriteria();
GLAccoutCritetia.Add(Condition.Eq(GLAccount.Names.Name, "Capital Souscrit Ou Capital Personnel" ));
//send filter request to API
GLAccount GLAccountGetByFilter = folderPARFIWEB.GetFilter<GLAccount>(GLAccoutCritetia);

2. Retrieve a list of GLAccounts

  • Get All

Return all GLAccounts in current folder. With large amounts of data, this method will take time to process

Get all GLAccounts
1
2
//get all GLAccount
IList<GLAccount> lstAllGLAccounts = folderPARFIWEB.GetAll<GLAccount>(1);

Get Filter All

Return all GLAccounts in current folder which match the given condition

For example, GLAccount has relation with Vat, and each Vat is unique. Now we want to find all GLAccounts that have relation with "BS0" Vat, we have the code like this:

Get filter all GLAccounts
1
2
3
4
5
6
// Get Filter All
// Find all GLacount which have Vat.Code is 'BSP21'
ICriteria criteriaFilterAllGLAccount = new GLAccountDAO().CreateCriteria();
criteriaFilterAllGLAccount.CreateAlias( "vatAccount" , typeof (Vat), Vat.Names.Id, GLAccount.Names.Vat_Id);
criteriaFilterAllGLAccount.Add(Condition.Eq( "vatAccount." + Vat.Names.Code, "BSP21" ));
IList<GLAccount> lstGLAccountFilterByVatCode = folderPARFIWEB.GetFilterAll<GLAccount>(criteriaFilterAllGLAccount);

 

3. Update one GLAccount

Update by Id

Update GLAccount by Id
1
2
3
4
5
6
// update a GLAccount by id
// this is the GLaccount i have from RAPI with Id inside
// Now i update 2 property and send back to api
GLAccountById.Memo = "this is the memo for demo updating GLAccount By Id" ;
GLAccountById.MemoType = MemoType.Green;
folderPARFIWEB.UpdateById<GLAccount>(GLAccountById);

 

Update by Code

Update GLAccount by Code
1
2
3
4
5
6
//Update a GLAccount by code
//This is the GLAccount we have from RAPI without Id inside, just the code
//Now we update 2 properties and send back to API
GLaccountByCode.Memo = "this is the memo for demo updating GLAccount by Code" ;
GLaccountByCode.MemoType = MemoType.Yellow;
folderPARIWEB.UpdateByCode<GLAccount>(GLaccountByCode);

 

Another way for updating GLAccount 

Besides the 2 methods UpdateByCode and UpdateById, we could use method ‘inserting’ for updating an existing GLAccount. Just create a new GLAccount that has the same code or id as an existing GLAccount, edit property and send back to API .
By checking existing Code or Id, API will know this insert-request is actually an update-request
**When sending back to API, client could skip the validation step by setting IsValidate = false. We don't need to validate the mandatory field in here, because this GLAccount already exists and all mandatory fields already exist in database too

 

Another way to update GLAccount
1
2
3
4
5
6
7
8
//Another way for updating GLAccount
GLAccount updateGLAccount = new GLAccount();
//There's already a GLAccount with this code in API database
updateGLAccount.Code = "120000" ;
updateGLAccount.Memo = "This is the memo for updating GLaccount 120000" ;
updateGLAccount.MemoType = MemoType.Green;
//Send back to API, skip the validation step by setting parameter isValidated = false
folderPARIWEB.Insert<GLAccount>(updateGLAccount, false );

4. Update a list of GLAccounts

Update Collection

With collection, we have the same rules like a single one. Method UpdateCollection() has input parameter as a list of GLAccounts

Update list of GLAccounts
1
2
3
4
5
6
7
//Update list of GLAccount
foreach (var GLAccount in lstGLAccountFilterByVatCode)
{
     GLAccount.Memo = "this is the demo for updating GLaccount " + GLAccount.Name;
     GLAccount.MemoType = MemoType.Green;
}
folderPARFIWEB.UpdateCollection(lstGLAccountFilterByVatCode);

5. Add one GLAccount

Without sub-entities

When inserting a new GLAccount, we need to remember to fill in all mandatory fields. With setting IsValidate, before sending request, Apis will check all mandatory fields to see whether they are presented or not. This is a necessary step because we don't want to waste time sending request when surely that request will be failed.
But in some scenarios, if client already checks and makes sure data is okay, it's okay for skipping this validation step by setting IsValidate = false
In GLAccount we have 4 mandatory fields: Code, Type, Side, MemoType . This means when creating a new GLAccount, 4 fields must have values

Add one GLAccount without sub-entiies
1
2
3
4
5
6
7
8
// Add one GLAccount
GLAccount newGLAccount = new GLAccount();
newGLAccount.Code = "180617" ;
newGLAccount.Type = 0;
newGLAccount.Side = 0;
newGLAccount.MemoType = MemoType.Green;
newGLAccount.Name = "Led Zeppelin7" ;
folderPARFIWEB.Insert<GLAccount>(newGLAccount);

With the sub entities created at the same request

Cascade property in glaccount

Some sub-entities inside GLAccount are marked as cascade properties. With cascade save-update, when GLAccount is saved/updated, API will check the association and save/update any property that is marked cascade
In GLAccount we have 7 properties which are marked as cascade:

  • NamesCurrent: all-delete-orphan
  • GLAccountDisallowedExpenses: delete-orphan
  • GLAccountALDimensions: delete-orphan
  • TotalBalancesCurrency: delete-orphan
  • TotalBalances: delete-orphan
  • BalancesCurrency: delete-orphan
  • Balances: delete-orphan

Add a new GLAccount with sub-entities inside
//ad one GLAccount with subEntity inside
GLAccount newGLAccountWithSubEntity = new GLAccount();
newGLAccountWithSubEntity.Code = "203718" ;
newGLAccountWithSubEntity.Type = 0;
newGLAccountWithSubEntity.Name = "Alfonso Christopher" ;
newGLAccountWithSubEntity.MemoType = MemoType.Green;
// set Category is an existing GLCategory with code VI
newGLAccountWithSubEntity.Category = new GLCategory();
newGLAccountWithSubEntity.Category.Code = "VI" ;
//NamesCurrent is a sub-entities with have cascade all-delete-orphan
newGLAccountWithSubEntity.NamesCurrent = new List<GLAccount_Name>();
// Create new GLAccount_Name
GLAccount_Name GLAccountName = new GLAccount_Name();
GLAccountName.GLAccount = newGLAccountWithSubEntity;
GLAccountName.Name = "Alfonso Christopher" ;
GLAccountName.BookYear_Id = new Guid( "F8999D9A-7EB6-471C-A48F-9F9400B4C5BE" );
GLAccountName.Language_Code = "en" ;
// add back to lst NamesCurrent
newGLAccountWithSubEntity.NamesCurrent.Add(GLAccountName);
// remember to set entityLevel equal to level we modify data
folderPARFIWEB.Insert<GLAccount>(newGLAccountWithSubEntity, 2, true );

6. Add a list of GLAccounts

Insert a list GlAccounts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//insert a list of GLAccount
List<GLAccount> lstNewGLAccounts = new List<GLAccount>();
Dictionary< string , string > dictionGLCodeAndName = new Dictionary< string , string >() { { "259634" , "Cash EUR" }, { "299343" , "HN-saving seabank USD" }, { "147365" , "Advances detailed by receivers" } };
foreach (var GLCodeAndName in dictionGLCodeAndName)
{
     GLAccount newGLAccount = new GLAccount();
     newGLAccount.Code = GLCodeAndName.Key;
     newGLAccount.Type = 0;
     newGLAccount.Side = 0;
     newGLAccount.MemoType = MemoType.Green;
     newGLAccount.Memo = "this is the memo for " + GLCodeAndName.Value;
     newGLAccount.Name = GLCodeAndName.Value;
     lstNewGLAccounts.Add(newGLAccount);
}
folderPARFIWEB.InsertCollection(lstNewGLAccounts, 2);

7. Delete one GLAccount

Delete by Code

Delete a GLAccount by Code
1
2
//Delete a GLAccount by Code
folderPARFIWEB.DeleteByCode<GLAccount>( "180617" );

Delete by Id

Delete by Code
1
2
//Delete By Id
folderPARFIWEB.DeleteById<GLAccount>( "AB952BD6-1CE5-4E37-B020-02ABC1D835D1" );

8. Delete a list of GLAccounts

Delete GLAccount by filter
1
2
3
4
5
//Delete by filter
List< string > lstGLaccountCode = new List< string >() { "259634" , "299343" , "147365" };
ICriteria filterDeleteByCriteria = new GLAccountDAO().CreateCriteria();
filterDeleteByCriteria.Add(Condition.In(GLAccount.Names.Code, lstGLaccountCode));
folderPARFIWEB.DeleteFilter<GLAccount>(filterDeleteByCriteria);

9. Retrieve balances of one GLAccount

Retrieve the balances of one GlAccount
1
2
3
4
5
6
//retrieve the balances of one GLAccount
ICriteria GLAccountBalanceFilter = new GLAccountBalanceDAO().CreateCriteria();
GLAccountBalanceFilter.CreateAlias( "GLaccount" , typeof (GLAccount), GLAccount.Names.Id,
                 GLAccountBalance.Names.Parent_Id);
GLAccountBalanceFilter.Add(Condition.Eq( "GLaccount." + GLAccount.Names.Code, "241209" ));
IList<GLAccountBalance> GLAccountBalance = folderPARFIWEB.GetFilterAll<GLAccountBalance>(GLAccountBalanceFilter);

10. Retrieve balance of list of GLAccounts

Retrieve balances of a list GlAccount
1
2
3
4
5
//Retrieve the balance of a list GLAccount
ICriteria GLAccountBalanceFilterByListGLAcc = new GLAccountBalanceDAO().CreateCriteria();
GLAccountBalanceFilterByListGLAcc.CreateAlias( "GLAccount" , typeof (GLAccount), GLAccount.Names.Id,GLAccountBalance.Names.Parent_Id);
GLAccountBalanceFilter.Add(Condition.In( "GLAccount." + GLAccount.Names.Code,  new string [] { "340000" , "416001" , "451600" }));
IList<GLAccountBalance> lstGLAccountBalances = folderPARFIWEB.GetFilterAll<GLAccountBalance>(GLAccountBalanceFilterByListGLAcc, 2);

GLTransaction


1. Retrieve a list of transactions of one Customer

  • Not matched (with pagination)

One GLTransaction could belong to one Customer and one Customer could have many GLTransactions.

So to find all GLTransactions of "STAR" Customer,  we need to make a projection from GLTransaction table to Customer table with condition: Customer's Code = "STAR".
1
2
3
4
5
6
7
8
9
10
//Retrieve transactions of one customer : not matched
ICriteria getTransactionOfOneCust = new GLTransDAO().CreateCriteria();
getTransactionOfOneCust.CreateAlias( "customer" , typeof (Customer), Customer.Names.Id,
                 GLTrans.Names.Customer_Id);
getTransactionOfOneCust.Add(Condition.Eq( "customer." + Customer.Names.Code, "STAR" ));
getTransactionOfOneCust.Add(Condition.Or(Condition.IsEmpty(GLTrans.Names.GLMatch_Id),
                 Condition.IsNull(GLTrans.Names.GLMatch_Id)));
getTransactionOfOneCust.SetMaxResults(20);
getTransactionOfOneCust.SetFirstResult(0);
IList<GLTrans> lstGLTransOfCustomer = folderPARFIWEB.GetFilterAll<GLTrans>(getTransactionOfOneCust);
  • Between two periods

Transaction of one Customer between 2 periods
1
2
3
4
5
6
7
8
9
10
/Retrieve transaction of one customer between between 9/2011 and 5/2012
ICriteria getTransBetween2Periods = new GLTransDAO().CreateCriteria();
getTransBetween2Periods.CreateAlias( "customer" , typeof (Customer), Customer.Names.Id,
                 GLTrans.Names.Customer_Id);
getTransBetween2Periods.Add(Condition.Eq( "customer." + Customer.Names.Code, "STAR" ));
getTransBetween2Periods.CreateAlias( "bookPeriod" , typeof (BookPeriod), BookPeriod.Names.Id,
                 GLTrans.Names.BookPeriod_Id);
getTransBetween2Periods.Add(Condition.Gt( "bookPeriod." + BookPeriod.Names.Begin, new DateTime(2011, 9, 1)));
getTransBetween2Periods.Add(Condition.Le( "bookPeriod." + BookPeriod.Names.End, new DateTime(2012, 5, 31)));
IList<GLTrans> lstGLTransBetween2Period = folderPARFIWEB.GetFilterAll<GLTrans>(getTransBetween2Periods,2);

2. Retrieve a list of transactions of one GLAccount

Retrieve a list transactions of one GLAccount
1
2
3
4
5
6
//Retrieve transactions of one GLAccount
ICriteria getTransOfOneGLacccount = new GLTransDAO().CreateCriteria();
getTransOfOneGLacccount.CreateAlias( "GLAccount" , typeof (GLAccount), GLAccount.Names.Id,
                 GLTrans.Names.GLAccount_Id);
getTransOfOneGLacccount.Add(Condition.Eq( "GLAccount." + GLAccount.Names.Code, "200000" ));
IList<GLTrans> lstGLTransOfGLAccount = folderPARFIWEB.GetFilterAll<GLTrans>(getTransOfOneGLacccount);

 

Top