Hi All,
CompanyMask – is a special column that stores binary mask that defines where this record should be visible and where you can update this record.
- Your table should have CompanyID and CompanyMask columns. Without CompanyMask data will be completely separated with no way to read it from other tenant from code.
- CompanyMask should be configured to allow other tenants select and update this record. Mask contains two flags for all companies. First flag – s it possible to select this record from particular company or not. Second flag – is it possible to update this record from particular company or not. So as more companies you have in database, as longer will be a company mask value.
- Companyes should be arranged in proper tries. In company table we have ParentID column, that stores hierarchy of companies. Only child companies can see records of parents companies. Parent companies not able to select date of child companies. Also companies from different chains not able to so get data of each other.
CompanyID
|
Name
|
ParentCompanyID
|
IsReadOnly
|
CompanyKey
|
1
|
System
|
1
|
||
2
|
Demo
|
1
|
0
|
Demo
|
3
|
Shared
|
1
|
1
|
|
4
|
Production
|
3
|
0
|
Production
|
5
|
Testing
|
3
|
0
|
Testing
|
CompanyID
|
Username
|
Password
|
PasswordChangeOnNexLogin
|
CompanyMask
|
1
|
Admin
|
Setup
|
1
|
0xAAAA
|
CompanyID
|
Username
|
Password
|
PasswordChangeOnNexLogin
|
CompanyMask
|
1
|
Admin
|
setup
|
1
|
0xAAAA
|
2
|
Admin
|
123
|
0
|
0x0000
|
CompanyID
|
Username
|
Password
|
PasswordChangeOnNexLogin
|
CompanyMask
|
1
|
Admin
|
setup
|
1
|
0xA2AA
|
2
|
Admin
|
123
|
0
|
0x0C00
|
Chain of companies
If we have a chain of companies (companies 1, 3, 4 for example) then system will select data from all companies in the chain. But you should pay attention to the company mask, because some records can be invisible in destination company.
CompanyID
|
Username
|
Password
|
PasswordChangeOnNexLogin
|
CompanyMask
|
1
|
Admin
|
setup
|
1
|
0xA2AA
|
3
|
Admin
|
123
|
0
|
0x0C00
|
3
|
Bob
|
123
|
0
|
0x3000
|
3
|
Alise
|
123
|
0
|
0xAAAA
|
4
|
Admin
|
12345
|
0
|
0xC000
|
In this example we will get users alise with password 123 and admin with password 12345 from the forth company.
Starting from version 3.0 you can’t login into company if it has at least one child company.
Sharing
Sometimes you will need to share one record between two or more companies. For this task you will need an updatable flag of the company mask.
CompanyID
|
Username
|
Password
|
PasswordChangeOnNexLogin
|
CompanyMask
|
3
|
Admin
|
123
|
0
|
0xFFFF
|
4
|
Bob
|
123
|
0
|
0xAAAA
|
5
|
Alise
|
123
|
0
|
0xAAAA
|
In this example you will see 2 users (admin, bob) from company 4 and also 2 users (admin, alise) from company 5.
“admin” is shared between companies that have company 3 as a parent, and admin has the same password in all child companies.
If you login into company 4 and update users password to 12345 it will affect company 5 too.
CompanyID
|
Username
|
Password
|
PasswordChangeOnNexLogin
|
CompanyMask
|
3
|
Admin
|
12345
|
0
|
0xFFFF
|
4
|
Bob
|
12345
|
0
|
0xAAAA
|
5
|
Alise
|
123
|
0
|
0xAAAA
|
So now admin has the same password in companies 4 and 5 too.
Note, that new records will be inserted into the system with default mask. If you want to share new records, then you should change default mask to 0xFFFF.
Tables modes
All tables in acumatica database can be in 3 different modes:
1)Separate – Table does not contain CompanyMask column or default mask is 0x0000.
2)Split – Table contains CompanyMask column and default mask is 0xAAAA
3)Shared – Table contains CompanyMask column and default mask is 0xFFFF
You can use the following stored procedure to change table modes:
pp_splittable @tablename, @mode
@tablename – name of the table
@mode – 0 (Separate), 1(Split), 2(Shared)
As you understand now Acumatica uses sharing functionality to provide system data to all tenants inside one instance. All tables with system data that should be shared have CompanyMask column and it is configured for split mode.
During upgrade Acumatica just removes system company and inserts new one, thats available only because of storing system data separately. If you developing add-solution to acumatica, you also able to do the same and reserve one company for your system data.
Have a nice development!
Hi Sergey,
I had shared data for Children Company(CP_01) to see. When I’m saving data I want it Update from their Parent Company(CP_HO).
It just inserts new data for my table because that data hasn’t stored in DB before with value CP_01.
Can I customize by using “trigger” or the other thing to automatic update it with CP_HO? And how to do it If you know it?
Hi Long,
Make sure that company mask on the appropriate companies is set to 11111111 (or FF). This is shared mask configuration that will advise acumatica that record should be saved into the parent company and not in the current.
If that does not help, I need more details about your tables and configurations.
The first time I create it in Child Company they have CompanyId = 4, I change CompanyID to 2 and CompanyMask = 0xFFFF –> CompanyID = 2 and CompanyMask=0xFF
After that, I had edit and save update it from the page. They create 1 more CompanyID = 4 with CompanyMask = 0xC0 and Update CompanyID = 2 with CompanyMask = 0x7FFF
I had checked with 2 table: InventoryItem and Country, and I got the same results.
They always create new Record and update CompanyMask for all record relate.
Hi Long,
For new records you should have the correct default constraint on the Company Mask column. For shared records it is usually 0xFFFF. Could you please check that default if correctly configured?
If not, you can use pp_splittable to change table settings including constraint
If that does not help, could you please send me an email with screenshot of companies and tables settings
I had checked both tables. They had constraint default is 0xFFFF but it still can not update at current company.
So if I want to send email, how can I contact you?
Maybe is info@acumatica.com, am I right?
It’s means we can share data from any table we want, right?
If I want to share inventory from companyID = 2 to CompanyID = 3, I need to declare:
– CompanyID = 3 is child of CompanyID = 2
– Add CompanyMask for InventoryItem Table. Maybe declare more 2 flag.
Am I right with that think?
In general you are right. But on practice it is highly not recommended to do this for complex entities like Inventory. As inventory is linked with warehouse, prices, accounts, subaccounts, classes, barcodes – you have to share many tables, not just one. It is extremely hard to support.
However simple entities as users works well.
Thanks for your advice!
Hope I can’t understand this things to customize my project.