Can Vtiger be customized/configured to support different opportunity types?
For example, our company is a SAAS company that also provides training. That means we have 3 distinctly different opportunity types that we need to track:
New Sales: These opportunities go through a free trial before purchasing
Renewals: We need to invoice our customers and handle obtaining payment for their annual renewals
Training: We need the ability to track students who are signing up for a training class.
Each of the above 3 types of opportunities needs to go through very different sales stages. And, also have different information tracked for them along the way.
Basically....I'd like to "subclass" the opportunity object!
Related
After a basic introduction to Python thanks to an edX course and a chat with a friend who told me about Django, I thought I could implement a solution for my laboratory. My goal is to keep track of every reagent order made by everyone of us researchers to the suppliers.
After one month I have a pretty decent version of it which I'm very proud of (I also have to thank a lot of StackOverFlow questions that helped me). Nonetheless, there's one requirement of the ordering flow that I haven't been able to translate to the Django app. Let me explain:
Users have a form to anotate the reagent (one per form) they need, and then it is passed to the corresponding manufacturer for them to send us an invoice. It's convenient that each invoice has several products, but they all have to: a) be sold by the same manufacturer, b) be sent to the same location and c) be charged to the same bank account (it's actually more complicated, but this will suffice for the explanation).
According to that, administrators of the app could process different orders by different users and merge them together as long as they meet the three requirements.
How would you implement this into the app regarding tables and relationships?
What I have now is an Order Model and an Order Form which has different CharFields regarding information of the product (name, reference, etc.), and then the sending direction and the bank account (which are ForeingKeys).
When the administrators (administratives) process the orders, they asign several of them that meet the requirements to an invoice, and then the problem comes: all the data has to be filled repeatedly for each of the orders.
The inmediate solution for this would be to create a Products Model and then each Order instance could have various products as long as they meet the three requirements, but this presents two problems:
1) The products table is gonna be very difficult to populate properly. Users are not gonna be concise about references and important data.
2) We would still have different Orders that could be merged into the same invoice.
I thought maybe I could let the users add fields dynamically to the Order model (adding product 1, product 2, product 3). I read about formsets, but they repeat whole Forms as far as I understood, and I would just need to repeat fields. Anyway, that would solve the first point, but not the second.
Any suggestions?
Thanks, and sorry for the long block!
Additional context:
User can buy one or more items every time they shop. I'm trying to figure out the pros/ cons of two approaches. I've written out what I think are the Pros of each (no need to call out Cons since a Con of one can be written as the Pro of the other), but I want to get feedback from the community
Approach 1:
Build a single model, e.g., Items, where there is a record for every item in the transaction.
Pros:
Generally simpler, one model is always nice
Aligns well with the fact that items are priced and cancelled/ refunded individually (i.e., there's not really anything discount or fee occurring at the Purchase level that would either 1) not be allocated to individual items or 2) not merit its own model)
Approach 2:
Build two models, e.g., Purchases and Items, where Purchases is a parent record that represents that transaction, and Items are the child records that represents every item bought in that transaction.
Pros:
For the business, I think it's easier in two ways: 1) it's easier to run analytics to figure out for example how many items people want to buy each time they make a purchase transaction (this isn't impossible with Approach 1, but certainly easier with Approach 2), and perhaps most importantly: 2) from a fulfillment perspective, it seems easier to send the fulfillment center one Purchase with many items since the delivery dates will all be the same, rather than a bunch of Items that they then have to aggregate (again it's not impossible with Approach 1, but much easier with Approach 2)
This can get quite complicated, and in the past I've used far more advanced versions of #2. You want to normalise your data as much as possible (lookup database normalisation for further info) to make it easier to run reports, but also to maintain consistency of data and reduce duplication. In some real-world scenarios, it's not always possible to fully normalise, and processing performance considerations also play a part simetimes - if you fully normalise data, you split your data into many small chunks (e.g. rows in tables) but to reconstruct your data you then have to retrieve it from many locations (e.g. multiple database queries) which has a performance hit.
Go with #2, and thoroughly plan how you are going to structure your data before you get too far into coding it. For a well-structured model, it should be reasonably straightforward to expand on the system in future. A flat structure can become a nightmare to maintain.
I'm creating a web based point of sale (think cash register) solution with Django as the backend. I've always taken the 'classic' approach of modeling invoices and their line items.
InvoiceTable
id
date
customer
salesperson
discount
shipping
subtotal
tax
grand_total
[...]
InvoiceLineItems
invoice_id // foreign key
product_id
unit_price
qty
item_discount
extended_price
[...]
After attempting to research best practices, I've found that there aren't many - at least no definitive source that's widely used.
The Kimball Group suggests: "Rather than holding onto the operational notion of a transaction header “object,” we recommend that you bring all the dimensionality of the header down to the line items."
See http://www.kimballgroup.com/2007/10/02/design-tip-95-patterns-to-avoid-when-modeling-headerline-item-transactions/ and http://www.kimballgroup.com/2001/07/01/design-tip-25-designing-dimensional-models-for-parent-child-applications/.
I'm new to development (only having used desktop database software before) - but from my understanding this makes sense as we can drill down the data any way we want for reporting purposes (though I imagine we could do the same with the first method by joining the tables).
My Questions
The invoice ID will need to be repeated for each row (so we can generate data like totals for the invoice). Is this an intentional feature of this way of modeling the data?
We often have invoice level data like notes, discounts, shipping charges, etc. - How do we represent these using this method? Some discounts are product specific - so they belong on the line item anyway, others are invoice wide (think of a deal where you buy two separate products and receive a discount on the two) - we could we somehow allocate it across the line items? Same with shipping charges, allocate it by dividing it among the line items?
What do we do with invoice 'notes' - we have printed and/or internal notes, would we put the data in the line items and just repeat it for each line item? That seems to go against data normalization. Put it in a related table?
Any open source projects that use this method that I could take a look at? Not sure how to search for them.
It sounds like you're confusing relational design and dimensional design.
A relational design is for facilitating transaction processing, and minimizing data anomalies and duplication. It's your operational database. A dimensional design is for facilitating analysis.
A relational design will have an invoices table and a line_items table and a dimensional design will have a company_invoices_customer fact table with a grain of invoice line item.
Since this is for POS, I assume you want a relational design first.
As for your questions:
First there are tons of good data modelling patterns for this scenario. See https://dba.stackexchange.com/questions/12991/ready-to-use-database-models-example/23831#23831
The invoice ID will need to be repeated for each row (so we can
generate data like totals for the invoice). Is this an intentional
feature of this way of modeling the data?
Yes
We often have invoice level data like notes, discounts, shipping
charges, etc. - How do we represent these using this method?
Probably easiest/simplest to have a "notes" field on the invoice table.
For charges and discounts you should use abstraction (see Table Inheritance), and add them as Order Adjustments. See the book by Silverston in the link above.
Some discounts are product specific - so they belong on the line item
anyway, others are invoice wide (think of a deal where you buy two
separate products and receive a discount on the two) - we could we
somehow allocate it across the line items?
The price of the item should be calculated at runtime based on it's default price, and any discounts or charges that apply in the current "scenario", example discount for government, nearby, on sale day. You could have hierarchical line items that reference each other, to keep things in order. Again, see Silverston book.
What do we do with invoice 'notes' - we have printed and/or internal
notes, would we put the data in the line items and just repeat it for
each line item?
If you want line item notes, add a notes column on the line items table.
That seems to go against data normalization. Put it in a related
table?
If notes are nullable, and you want to be strict about normalization, then yes, add a invoice_notes table.
I need to design a traditional sort of "get customer by ID" SOAP service operation. The thing is that customer data is retrieved from about 15+ systems, and depending on the customer's geographical location, different data needs to come back in addition to the traditional base set of facts about a customer (name, address, phone number, etc).
There are therefore two types of customer information at hand:
Common customer data that can fit into a "canonical data model" type bucket, e.g. name, address, etc.
Region-specific customer data that is specific to a customer's region or country. Think social security number if you're in the U.S., National Insurance number if you're in the UK, and so on.
Customers can be from a wide range of regions and as a result if we were to follow the approach of a traditional customer base type and a number of extensions e.g. USACustomerType which extends the CustomerType base type, we'll quickly run into two issues:
The WSDL will be huge
The WSDL will have large bits of information that are irrelevant to large amounts of people
I'm trying to avoid both of these things.
The options I have thought of, all in my opinion quite mediocre, are:
Have only a base customer type and an unbounded list of name-value pairs, and different systems can add their own name-value pairs, and consumers looking for that data could look for those (this is nice and extensible, but just not a very good idea)
Bite the bullet and have a giant WSDL that has a CustomerType base type and a number of extensions, adding more nations as they become available
A variation on #2, which is have only a base CustomerType and a large number of optional fields
I suppose the question is: Have you run into a situation like this and if so, how did you deal with it?
I wish to create with a database with following models and constraints.
1) Student with attributes name, roll number
2) Exam with attributes exam_code, exam_subject
3) Option with attributes option_name, and ManyToManyField on Exam
4) Application with user, exam, ManyToManyField on Options(new)
Basically there will be many exams and options. Student is entitled to choose a subset of options pertaining to his examination choice.
edit: With the new model Application, I suppose the problem boils down to using javascript in the interface for limiting the options available in the interface.
The next challenge lies in handling students with multiple subjects and their subset of options should be a intersection of options(as two different exams might have options in common) available for both exams. Any guidance on this part would be great.
As it stands right now, the Student doesn't really play into the equation. All that matters is what options are available for the particular exam in question (where Student is only nominally related in that the particular exam is a data point on it).
So, that being the case, the available options to a student is always a function of:
some_student.exam_taken.available_options.all()
What you may be wanting, is the ability for a student to have taken multiple exams, and then have all of the available options for all of the exams taken -- a sort of aggregate.
If that's the case, first, you would require a M2M relationship established between Student and Exam (instead of the Foreign Key). Then, you could get all available options from all exams via:
Option.objects.filter(exam__student=some_student).distinct()