Background
Currently except Single and Report, each new doctype will create one dedicated database table, for business transactions cover different business scenario(type) like Payment Entry to handle both Receive and Pay, per current design it is to be modelled in one doctype with control field: payment type, user can use the same form by selecting different payment type and input other depending fields to do his/her Receive or Pay payment.
Problem
-
Covering all different business scenarios in one doctype/form by using control field to generate dynamic form is a great feature, but it often makes the single complicated doctype hard to maintain and evolve for new business scenario, and on user side, the actual form (user interface) for specific business scenario especially those simple one displayed a lot of irrelevant fields.
-
As business scenario(Payment type) is Select other than Link field, there is no easy way to restrict user to create/change only one specific business type(Receive) while displaying other(or all) scenarios.
-
Even though there is permission level at field level to control field’s availability per assigned role for each user, but doctype wise(database table) field level permission rule applies to all business scenarios on the same doctype. no easy way to adapt field level control per business scenario( records level).
Solution
multi doctypes (doctype variant) per database table,
use existing standard doctype as base doctype which defines all available fields in database table(the model), at the same time base doctype defines the default form(user interface, the view), other new doctypes (doctype variant) which has base doctype assigned can base on or add extra fields to base doctype’s database table, define other alternative form(view) for specific business scenario. in other word, there will be only one data source stored in database table, with different presentation( form ) per different business requirement.
in MVC( Model, View, Control) architecture, it is one model, one controller with multiple views. in SAP, it is called transaction variant, in Odoo, it is multi (form) views per model(defined in py file).
How it works
frappe.core.doctype.doctype.doctype
add 2 fields: base_doctype and filter to DocType doctype
-
base_doctype is the doctype which already mapped to database table, no base_doctype assigned to it or base_doctype is the same of the doctype name
-
for any new doctype with assigned to base_doctype,no new database table will be created, instead the corresponding base_doctype’s database table will be altered accordingly. the py controller class will have the base_doctype’s class instead of the generic Document as parent class.
-
Filter field defines the SQL where condition which will be applied to the get_list call to this doctype, this is to be acted as the permission control mechanism.
model.document.py / model.base_document.py/ model.db_query.py/database.database.py
each db.sql call with doctype as paramter , replace it with base_doctype as necessary
model.db_query
append the doctype.filter as where condition
desk.form.load
getdoc: if user has no permission for the base doctype, auto switch to the doctype variant with read.
other use cases
-
Provide 2 versions of sales order form to different users, standard version with all information to sales order user and sales manager, simplified version with limited fields, i.e hide the sensitive price and amount info for other users
-
Service item (base doctype Item) with service item relevant fields and filtered by item group equals to service,
-
Material Receipt doctype (base doctype Stock Entry) with Stock Entry Type Material Receipt as default, hidden, assign this doctype to Material Receipt Role, assign only this role to warehouse keeper responsible for material receipt.
I have done the development on my local instance and tested by myself till now, it is kind of moderate change to the core, per discussion with core team, only if there is real customer use case, and the customers strongly support this new feature by put some money to it, and someone is going to use and test it in PRODUCTION, then there is chance it can be accepted into the core.
So I PIN this post on top for sometime to get the community feedback, please show you support by lIKE it or PM me.
PR is here
https://github.com/frappe/frappe/pull/7946
This PR is submitted for interested potential customer to see the code changes needed for the feature, adopt it into their own local system, test it and release to the production system to verfiy it works as expected, then there is chance for the core team to start review and consider merging into the core.
Many thanks.