I am working on one HRMS application. There is one Transfers workflow in application. As a part of it employee can get transferred from one department/office to other department/office.
Transfers process works as below:
Employee checks for vacancy in application and applies for transfer if vacancy is available. Once employee submits transfer form, it goes for approval to employee's department/office. There are 5 approver in approval flow. In PostgreSQL to achieve 3NF I have decided to create 3 separate tables as below:
1) One for employee's transfer request
2) Transfer request approval request
3) Transfer request approval request details
So in above image you can see for approval request I have created two separate tables i.e. transfer_request_approval and transfer_request_approval_details. transfer_request_approval refers transfer_request_id as FK and transfer_request_approval_details contains transfer_request_approval_id as FK and all 5 approver's record for that particular approval request.
e.g. We have transfer request with id=1, so there would be one row in transfer_request_approval table (e.g. transfer_request_approval_id = 1, transfer_request_id = 1 as FK). In transfer_request_approval_details there would be 5 rows for 5 approver's records.
(Note: approval_status is either Approved or Reject or Rework, note is nothing but user can put some remark. If approver puts rework status it will go back to approver1 again e.g. if Approver5 put rework status it will go to approver1 again for same process. so there would be 10 records for that entire approval request in transfer_request_approval_details table).
Question : Do I really need to have transfer_request_approval_details table or I can include all those approvers records in transfer_request_approval table?
In order to maintain normal form, you need the approval details table separate, otherwise you end up with duplicate values of status for each approver. However, I see no need to have separate transfer_request and transfer_request_approval tables. Just add status to transfer_request and link to apporver_details.
I think you can include all those approvers records in the transfer_request_approval table.
There is no meaning in storing data in a separate 2 tables.
Related
I am building a website where users can view emails that are fetched from my gmail account.
Users can read emails, change their labels & archive them. Each email has metadata associated with it, and users can search through the emails based on the metadata. Furthermore, each user is associated with an organization. Changes made to an email (e.g., if the email is archived, or if the tags are changed) by any one user gets reflected across the organization.
Right now, I store all emails in a single table along with their metadata. However, the problem is that I now have over 20,000 emails in the database, and searching through them based on the metadata takes too much time.
Now one way to optimize this is that when a user runs a search command then the system should only search through emails that are in the inbox & not archived or deleted. But the issue is that where one organization might have archived an email, another organization might have not. So I can not create separate tables for Inbox & Archive. By default emails also get auto-archived after some time (this option can be disabled also), so the Inbox generally has around 4 thousand emails, whereas the archive has many many times that.
My question is does it make sense to create separate Inbox & Archive tables for each organization & just copy all new incoming emails to the tables? Since organizations only join by invitation, so I do not expect the total number to cross 100. Or would this just explode and become too difficult to handle in the code later on, with so many tables.
I am using PostgreSQL for this.
If your operational workflow says "upon adding a new customer create such-and-such a table" then you have a serious database design problem. When you have more than about 50 customers things will slow down due to per-table overhead. In other words, when you start to succeed in business you will start to fail in performance. Not good.
You have a message entity. It, no doubt, contains the message's text, subject, timestamp, from, to, and other attributes that form part of the original message. Each message will have a unique (primary key) message_id. But the entity should not contain attributes like inbox and archive, because those attributes relate to the organization.
You need an org entity. Each organization has a unique org_id, a 'name and other attributes of the organization.
Then you need an org_message table. Its primary key contains both org_id and message_id. And it will contain Boolean attributes like archived and read, and a VARCHAR attribute naming its current folder. So, each org's window into your message table is organized by the org_messages.
If you start with an organization named, for example, shipping, and you want to see all its messages, you use a query like this.
SELECT org.id, org.name,
message.*,
COALESCE(org_message.read, 0) unread,
COALESCE(org_message.archived, 0) archived,
COALESCE(org_message.folder, 'inbox') folder
FROM org
LEFT JOIN org_message ON org.org_id = org_message.org_id
LEFT JOIN message ON message.message_id = org_message.message_id
WHERE org.name = 'shipping';
The LEFT JOINs and COALESCEs work to set each org's defaults for each message to unread, not archived, and in the inbox folder. That way you don't have to create a row in org_message for each organization and each message until the org handles the message.
If you want to mark a message as read and archived for a particular org, you INSERT a row into org_message, using ON CONFLICT DO UPDATE
INSERT INTO org_message (org_id, message_id, read, archived, folder)
VALUES (?, ?, ?, ?, ?) ON CONFLICT DO UPDATE;
That either sets or updates the org's attributes for the messages
If you find that searching these tables is too slow, you'll need indexes. That's the subject of a different question.
Sorry if this is sort of confusing because I'm not sure how to word this. I am trying to create a workflow that runs off of Account's in Microsoft CRM 2011. One part of this workflow requires me to retrieve a field contained in the Business Unit of the User in the Account's "Created By" field. However, the workflow will only allow me to access the Business Unit itself, but not any of its fields.
I'm wondering if there is a simple trick or work-around that will allow me access to this data.
Thanks!
For reference, the Account has a User, who has a Business Unit, and the Business Unit has a field I need to access. CRM, however, doesn't want to let me get more than 2 levels deep when accessing fields.
Clunky but do-able if you accept a bit of denormalisation (temporarily or otherwise). I'll assume for the sake of example you want to get at the "cost centre" field from the BU.
Add a field on User entity to temporarily hold the value from the BU (so make it same type and length, text(100) in this case), optionally put it on the form.
Create a child workflow for the User entity to update the user with the "cost centre" value from their BU. Make it only available to run as a child, not onDemand or anything else. Activate
In your Account workflow, add a step to call the child workflow against the relevant user (eg Created By in your case).
Add a step to wait until the new cost centre field on the user record contains data.
Now do whatever you need to with the value from the user record, such as update the Account, or do some branched logic.
Whatever you do, once you have used the value, clear the field on the user record, or do this as the last step of the workflow.
Now, since Users don't change BU very often, you might actually just go ahead and keep that value on the User record permanently, and instead of a child workflow, simply run this on create of a new user, or on change of BU, and store the value permanently on the User record. Yes, it is 'denormalised' and not purest SQL design, but then you don't need a child workflow, you don't need a wait state and you don't have to clear the value at the end, or worry about what happens when two Accounts need to run their workflow at the same time. I include the more general approach above as this might apply to other records which do change their parent quite often.
Just an additional thought - you can access the "owning business unit" of the Account, but this will be the BU of the Owning User, rather than the Created By, but is your business process such that this would normally be the same person? (eg users only have Create priviledge to "user owned" depth, so can only create records they own).
If so, then you could get at the BU directly from the Account, and then any fields on it too (in a condition or to update the Account)
Alternative which is less ideal but a similar approach - add a relationship from Account to BU (eg "created BU"). Now you can update the Account with this by referring to the Created By User's BU, then in the next step, reference this value from the Account. This is again denormalised, and less preferable since number of Accounts is far greater than number of users, so the level of duplicate information is much higher.
You can't get deeper with the standard steps of a workflow.
The solution is to create a custom workflow activity, you can start from this article:
http://msdn.microsoft.com/en-us/library/gg328515.aspx
I am using the BusinessObjects Enterprise server and i have a report that uses the "department" as a parameter field to control the selection of records. there are 20 different departments.
I want to schedule this report to run 20 times with a new single department selected each time. Is there a way to do this without scheduling the report 20 times?
thanks for any help
Yes, you can. A bit of a process:
Create a Group for each department
Add users to groups as desired; ensure that they have an email address
Create a Profile; add a Profile Value for each Group (one Profile Value for each Group/Department ID combination); the Profile Values will be strings (important)
Create a Publication; add your report to the Source Document; add the Groups that you created earlier to the Enterprise-Recipient list
now define the Personalization (the key part of this); you can either add a Filter (set TABLE.FIELD or FORMULA to your Profile (Report Field & Enterprise Recipient Mapping columns) OR set the Department ID parameter to the appropriate Enterprise Recipient Mapping value (your parameter needs to be a string for this to work; note comment earlier).
set Destination to Email
set other properties (e.g. Format) as desired
Save & Close
You can also schedule this Publication to occur on a recurring basis.
Notes:
This solution uses the Publication Job Server (runs the Publication), the Crystal Reports Job Server (to run the report), the Adaptive Processing Server (does the bursting), and the Destination Job Server (send the email messages). You may want to create a separate set of these services and package them into their own server group, then force the Publications to use only this server group.
Related to the earlier point, you may want to create a server group just for scheduled reports and force recurring instances to use this server group. Why? Publications don't seem to do a good job of waiting for reports in a queue--if a Crystal Reports Job server isn't available, the Publication will fail. Forcing scheduled-report instances to generate on their own server group helps to eliminate this issue.
If you make significant changes to the report (e.g. add a parameter), you may need to remove then add the report to the Source-Document list to ensure that it has the most-recent definition; other changes to the report (e.g. adding a column) don't seem to require this attention. YOUR MILEAGE MAY VARY.
You can design the report with the department as a group.
Have a new page after each group and be sure to print the records from the department group section, not the details.
This is assuming you are getting all the departments inside your database fields.
This is my first project which I've encountered that I can't get by on NSUserDefaults peppered with some NSCoding protocol. I've been asked to write some POS software.
Essentially, the App needs to store a bunch of products, prices and sales accounts. The user should be able to add items and accounts, and track the balance of accounts over time. The balance of an account should be able to be carried over from one "Session" (time period) to the next.
I'm comfortable with the concepts, but I'd like to be confident that I'm modeling this right. Here's how I've modeled my data. I'd like to know if I've done this properly or if there are any glaring errors/omissions.
I've created an "Account" Entity, which has the following properties:
First Name
Last Name
Account ID
Group
There is a relationship to the transaction entity.
I've created an entity for each Session. Again, a session is just like a fiscal month. The session will have a custom name and an ID.
Session ID
Session Name
There is a relationship to all of the accounts that are applied to that session.
There are of course, products, which have a name and ID. There is also a relationship to the "price" object, so I can change the prices without affecting balances.
Please see this screenshot from Xcode 4 which explains my model in its entirety:
Edit:
Looking at this, it seems that I'm missing some important info, such as dates of transactions etc. That said, am I on the right track?
It has been my experience that point of sale transactions list all the data that is necessary to recreate the receipt in three tables, a header (think date of sale, singular tracking entity), a set of records for all items being sold (linking back to the sale header), and a set of records for all the methods of payment (again linked back to the sale header).
This will give you the opportunity to rebuild the individual transactions in the future. Also, this is a simplistic model, but should suffice for what you're asking. Nominally yo uwould also keep track of applied discounts on a per-line-item basis, and per-invoice discounts, and per-group discounts, and etc.
What's the relationship between sessions and transactions?
You probably don't need to have an entity for price, as it will likely just be a float. I'd recommend adding a price attribute to your product entity instead.
I don't know if transactions will need names or not, I suppose if you want to have notes then they should.
Also transactions should probably have a to-many relationship with products.
Will this be used on a single device or will there be many users? If each user (account) is responsible for its own data then it may make more sense to have transactions/session rather than transactions/user.
Background:
I have a website (ASP.NET MVC) where users can write/edit/delete a "review".
Doing so needs to kick off a database trigger to update some global statistics on the system.
Database Tables:
Review (parent)
MetaData1 (Review 1 - 0..1 MetaData1)
MetaData2 (Review 1 - 0..1 MetaData2)
MetaData3 (Review 1 - 0..* MetaData3)
So Review is the main table (ReviewId - identity), and the other's are meta data.
The problem:
I have a stored procedure which performs the calculations, which needs to be called whenever a review is created/edited/deleted.
At the moment, i have a trigger which calls the SP on all tables (4 identical triggers). But this results in the stored procedure being executed possibly 4 times when it only needs to be done once.
I can't just put it on Review only, because if a user edits metadata for a review, Review table will not be touched and hence the trigger will not fire.
I need a way of saying "watch all of these tables for activity, when a record is created/edited/deleted, fire off this procedure once."
Any tips/suggestions/ideas?
FYI - i'm using Entity Framework 4 for the CRUD operations, if that matters.
Drop triggers on 3 MetaDataX tables. After saving metadata records, really change something ("last edited" time would be a good candidate) in the Review table.
You may want to write some proxy methods to implement the above logic in Review mapped class to manipulate the metadata objects (and do not use MetaDataX mapped objects directly).
Get rid of the entity framework and triggers. Create a stored procedure that updates four tables, and call that from your web page.