Jump to content

DeX

Members
  • Posts

    258
  • Joined

  • Last visited

Everything posted by DeX

  1. I wasn't necessarily going to build setters and getters for every single database column. For example, if I have a quote I need to display on the page, I would build a customer object and set all the customer details in that so the getters can retrieve it to display on the page, it's only name, address and phone number. Then I would have a quote object which would set things like the quote price, the quote expiry date and a list of all the upgrade options to show on the quote, along with their attributes like width, height and quantity. Then when doing purchase orders, I would build a bill of materials (BOM) object that would contain all individual building products and their attributes. Is this wrong? I'm mostly wondering how to separate the model into multiple models because I mainly just have one right now with all the methods in it.
  2. I've been working with what I thought was MVC for quite a while but now after researching it some more, it appears I may have been wrong all along. I think I have been using the model incorrectly. Is my new way of thinking now correct? Model: These are like objects that hold data during the session (page load). It can also dump the data to the database but is mainly used to hold data related to a specific object for use throughout the current page load. Controller: There will usually only be one as it is like a gatekeeper that directs requests to the proper model. View: These will usually be the .php pages themselves but for views that are reused, it can be an isolated class which generates HTML code (like loading a select element with user names). I have built a program where a quote is requested by the user and the program has to go to the database in order to get the details of the quote to display them on screen. Right now my view is making the request through the controller to the model and the model is fetching each piece of requested information from the database, then passing it back through to the view as needed. Because the page can show the same information in various places, the same database call by the model can be made more than once for that specific information. Should I be making a request for the entire quote, building a quote object with the model and then passing that entire object back to the view to be used instead? This will introduce a lot of getter/setts methods of which I currently have none. I'm assuming I would have a customer model which would build a customer object and return that. Then a quote model would build a quote object and return that. Same for purchase orders and users, all which will have information appearing on the quote or purchase order. Thanks a lot, I'm really trying to research this as much as I can and get it correct.
  3. At times, yes. Some SELECT elements will be duplicated on more than one screen, like the list of users. That can be used to assign a quote to a salesman or it can be used on the user management screen in the admin section.
  4. Does this mean I should just have the foreach loop in the webpage itself and build the option elements right there? This would mean I can avoid having a view class file at all, the view would simply be the webpage.
  5. Currently I have a page where a select element resides and it shows a list of all users in the system. Here is my logic for populating the select box: 1. That page makes a call to the view to be populated. 2. The view runs a foreach loop and builds a string containing a lot of options elements holding the user names, then returns the long string back to the page to be displayed. 3. The foreach from the view makes a call to the controller to get all the names. 4. The controller passes the request straight through to the model. 5. The model gets all the names from the database, adds them to an array and returns them back to the controller. 6. The controller passes them back to the view. 7. The view iterates through them and builds the list (in step 2 above). 8. Element with all options is displayed on page. I'm confused if the view is for building objects which contain HTML coding, or if the view is the actual webpage being displayed, and the building should be handed off to the controller. Basically I'm wondering if the view should be pages or classes.
  6. By repairing the schema, do you mean adding default data values to all those columns?
  7. I upgraded my server to Ubuntu 16.04 which also installed MySQL 5.7 with it and now every time I run an insert statement, it errors and tells me there is no default data specified for that column. If I go into PHPMyAdmin and specify default data for all columns, the insert will run without error. How do I turn this off? It's affecting my production sites, I just want it to go back the way it was of inserting empty strings or zeroes (or null) for any column I don't specify.
  8. You were right, that worked perfectly. Thank you!
  9. Wow that worked perfectly, thanks! I wonder why it does that.
  10. 7. I have other websites running on the same webserver and their code can find their respective javascript folders fine. 8. I didn't customize Apache2 at all, I just installed the default setup.
  11. I have an Amazon web server which I host maybe 5 websites on and one of them is a portal I'm building for a client. Everything works great except when I load a page that uses JavaScript files, the console complains that it can't find any of the files, so therefore none of the JavaScript code on the page works. Here is a comprehensive list of things I have tried: 1. I put a test.html file in the JavaScript directory and tried to load it in my browser. My browser told me it didn't exist, 404 error. 2. I created a javascript2 folder and put the test.html file in there, it loaded no problem. 3. I moved all of my JavaScript files out into the javascript2 folder and changed all the reference links in the HTML to point to the new folder. The page and all JavaScript functions worked perfectly. 4. I did a "locate .htaccess" on my server (Linux) and it didn't return anything inside the /var/www/X directory for the website. There were 1 or 2 inside some other /var/www/X2 or /var/www/X3 directories but none of them specified anything for a javascript directory. 5. I restarted Apache2 and restarted the server many times. 6. When I visit X/javascript/test.html in my browser, watch it fail, then check my Apache2 logs, nothing was added. For some reason my web server can find every file except for anything inside that javascript directory, I have no idea why.
  12. I have a job management portal which I built and it allows my client to create PDF files of quotes for their customers. They send their customer a link (token based URL) so their customers can click the link and view the quote. I want to serve up the PDF file on screen for their customer to view, how can I do this? Each time I attempt it, Chrome asks me if I would like to download the file. I just want to view it without the customer having a direct link to it.
  13. Great ideas, guys, I'm going to do this for sure, the other added benefit of your suggestions is that Google can no longer spider the PDF and show them to anyone Googling a name. I think I already avoided this with my robots.txt but it has been a problem in the past. I think I will still move the PDF folder outside the web directory just to make it easier to roll out updates, I no longer have to skip the PDF folder when moving all folders into production. I can just use a symlink to get the same functionality or just serve it up with PHP like someone suggested.
  14. I have a portal system I built that allows users to generate a quote PDF and save it onto the server so they can send the link to a customer for review. Is it common practice to leave the PDF directory web accessible or should it be one level above the web directory? These quotes do need to be viewed by the public since the salesmen simply send the URL to the customer for review but I've seen it done both ways. Thanks.
  15. That's odd, I wrote some quick sample code to post here for you but my example code works. I'll have to go back and work through my code to see where the problem is with that then. Oh well, I'll leave the example code here for someone else in case they're looking for one. <html> <head> <title>TODO supply a title</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> <script type ="text/javascript" > function test(element) { alert($(element).find(":selected").text()); } </script> </head> <body> <select onchange ="test(this);" > <option value ="1" >One</option> <option value ="2" >Two</option> </select> </body> </html>
  16. I've seen many solutions on various searches using :selected or options:selected or .text(). I've tried all of these in both JavaScript and JQuery, all of them give me the same result. When I change the selected option of a SELECT element and then run the JavaScript statement, it returns the original SELECT value before I changed it, not the current value. I've tried both .text() and .val(), both give me the same result. I realize I'm not posting the code but it's literally just a SELECT element with 20 options and some JavaScript to get the text from that element.
  17. You mean create a class object and use getters / setters?
  18. I'm only using the first array element of overallQuantities for most elements but like the wallMetal example I posted above, some items have more than one quantity group because there are different quantities at different lengths. Like overhead doors, you might have 3 at 10x12 and then another 5 at 12x12. So then the quantities array would have 2 elements in it. How would this work for getting the total price? If the building costs $300,000 and part of that is corner moulding, what is the new price when the quantity of corner moulding has changed? Am I keeping another array of the total prices for each product and tallying the total price of the building based on adding them all together? Then I would have to re-add them if one of the quantities change. Is that right? So now I'm trying to understand what you're doing with the BOM because I really want to implement this in the system. So let me try and walk through an example here to see if I can figure out how this works. overallQuantities[main_item_id] = quantity overallQuantities[sub_item_id][main_item_id] = quantity overallQuantities[sub_sub_item_id][sub_item_id][main_item_id] = quantity This is the example you posted, if I'm making a change which will update the quantity of corner moulding, would the corner moulding be the sub-item or main-item in this example? Going from the beginning: - an edit is done on the web page (building length changed) - AJAX function is called - AJAX function passes in the name of the changed element as well as the value of that element - corner moulding quantity requires updating based on the changed element and its value - overallQuantities[cornerMoulding] is updated using the huge quantity calculation assigned to corner mouldings - overQuantities[cornerMoulding][whiteScrews] is updated using the quantity calulation assigned to white screws which uses corner mouldings. Is that right? Did I use the main and sub items correctly there? - somehow the total price is updated and the new quote is displayed to the user. There are also other things on the quote which change based in some inputs. For example, if the sales guy changes the post spacing (distance between posts) from 6 feet to 4 feet, that's going to have an effect on the quantity of posts but it's also going to show up in an area at the top of the quote which states what the post spacing is. This isn't for every element, just for a couple, but post spacing is one of them. So this text would need to change to reflect the new post spacing, as well as show the new total price of the quote.
  19. Wow, that is genius! I actually laughed when I read it because of how smart that is. Because the system gets the overall price for the quote, it goes to the database 300 times to get the prices for all the different products with 300 individual database calls to the same table. I think it might only make the calls for products with a positive quantity though, now that I think about it. EDIT - These calls are only done when the quote is saved, not on edits. I'm not concerned right now about speed of saving quotes, currently I'm focused on edits.
  20. Yes, that's what I'm doing, it's just 4 columns: - id - quote_id - product_id - price Then I also have to save the sales person's commission rates: - operations commission - sales commission - sales management commission - 4 or 5 other commissions Then I save the rates: - winter build rate (used if building in winter) - remote labour rate (used if building far enough away from head office) And then I save minimums - minimum labour (used if labour is less than the minimum) - minimum materials (used if materials are less than the specified minimum) - minimum truss price (used if total truss price isn't at least the specified minimum) These are all things required for looking back at older quotes and they all come from separate tables and get stored into separate match tables.
  21. I know of all the ways to dump it to a text file but I want to save a database table into another match table. I have web software which allows users to enter some inputs and save a create a quote for their client. At the time of the quote, all of the building products in the database have an associated price and this pricing can change at any time. When they save the quote, I want to save all 300 products and prices into another table so I can go back later and see what the prices were when that quote was done. I don't want to load a quote from a month ago and have it price based on current pricing, I want it to price using the prices from a month ago. Right now I'm simply selecting all 300 rows and dumping them into a match table with the quote ID. That's causing it to take about 30-50 seconds to save the quote, along with a couple of other tables I'm saving as well. I'd like to make the quote saving much faster, is there a faster way to get this snapshot of the database table when the quote is saved?
  22. I've been using Workbench in Ubuntu for years without any problems at all, it hasn't crashed once. Another alternative you can try is Squirrel SQL, I know that also works for Microsoft SQL databases as well. I used it on a previous Microsoft project and it worked great but I still prefer Workbench for non-Microsoft databases.
  23. I don't know how to split your quote so I'll answer it in 2 parts here. As per your question in the first part, you're close but it doesn't quite work like that. I'm not updating quantities anywhere, I'm dynamically calculating the quantities each time they're requested. Let's use the following example: - quantityScrews = buildingWidth * 2; - quantity2x4 = quantityScrews / 3; - quantitySoffit = (quantityScrews > 100 ? quantity2x4 * 5 : quantityScrews + 4; So when a change is made in the program, I request the quantity of screws and it gets stored into the overallQuantities array for no other reason but to speed up the subsequent requests. That array isn't a master quantity array, it's just a quicker place to get the quantity instead of having to recalculate it again. So when I request the quantity of 2x4, it'll get quantityScrews from the overallQuantities array which (I assume) is faster than recalculating it again. I could be wrong but it sounds like you think I'm using that array as a quantity storage, then updating the quantities in there as needed, that's not the case. Should I be? The main calculation happening here is getFinalCost() which makes a request to get the total costs of all the individual products which makes a request to get all the quantities of each product. Those quantities are requested from the switch statement every time. On to the second part of your reply, the code you posted. I think you may really be on to something here but I don't quite understand it well enough to implement it. So let's say the sales guy changes the building to be 10 feet wider, the building width is used as a calculation in around 50% of the product quantity calculations so that's going to have a huge effect on the quantities of everything. More lumber, more posts, more metal, trims, insulation, everything. Also, you don't always have simple operators being applied, sometimes you have complicated IF statements like the quantitySoffit calculations above. Will that still work in your example? It looks like what you posted may work so I'd really like to understand it a bit better, please let me know if this is correct: - I would create a set of rules for all 300 products like you did for the 3 you posted above. - Then when the building length is changed, I would call the _calc method? Is that right? - What is the $rule variable I pass into _calc? I really like your top down idea but here are 2 more quantity calculations which I can't quite figure out how to convert to your example: This one is for interiorJTrim, it isn't too bad. There is an IF statement to see if the building is insulated because they're only used on insulated buildings. The $showInsulation variable is used to force an insulated price, I use that to get the price of the building if it were to be insulated, that allows the sales guys to print a cost on the quote for upgrading to an insulated building should the customer change their mind later. I can use that to query an insulated cost of their building by passing that value as true. You'll notice I changed all the product variables to constants but it didn't speed anything up. case (self::interiorJTrim) : $quantity = 0; if ($this->isInsulated() || $showInsulation) { $quantity += $this->getTotalQuantityManDoors($showInsulation, $showPerma) * 2.5 + $this->getTotalQuantityBuildingProduct(self::threeByThreeFixedWindow, $showInsulation, $showPerma) * 1.5 + $this->getTotalQuantityBuildingProduct(self::fourByThreeFixedWindow, $showInsulation, $showPerma) * 1.5 + $this->getTotalQuantityBuildingProduct(self::threeByThreeSlidingWindow, $showInsulation, $showPerma) * 2 + $this->getTotalQuantityBuildingProduct(self::fourByThreeSlidingWindow, $showInsulation, $showPerma) * 2 + $this->getQuantityCustomWindows() * 3 + $this->getTotalOverheadDoorQuantity() * 2 + $this->getTotalHeightBuildingProduct(self::biFoldDoor, $showInsulation, $showPerma) * 2 / 9 + $this->getTotalWidthBuildingProduct(self::biFoldDoor, $showInsulation, $showPerma) / 9 + $this->getTotalQuantityBuildingProduct(self::highLiftCharge, $showInsulation, $showPerma) * 1 + $this->getTotalQuantityBuildingProduct(self::atticHatch, $showInsulation, $showPerma) * 2; } $quantities[] = ceil($quantity); break; Now for the worst one, this is the quantity of wallMetal, it's probably the most complicated quantity calculation in the system: - First get a value based on all the overhead, sliding and bi-fold doors the sales guy added. - Then if it doesn't have exterior wall light, add more to the value. - Then generate a quantity of wall metal by REMOVING the value we just calculated because we need to remove any wall metal which will no longer be in the places of doors and wall light. Obviously those holes in the wall will now be filled with doors and wall light instead of wall metal. We don't want to charge the customer for that wall metal if we're not using it. - Then we calculate another quantity to add to the quantity array. The reason we're separating the quantities is because this quantity group of wall metal will have a different length. It's the same product in the system (wall metal) but when it gets printed out on the product list for the building construction, we need to know how many pieces of wall metal we have for each length. That length is calculated separately in the getLengthBuildingProduct method which is another switch statement. case (self::wallMetal) : $quantity = 0; $value = 0; for ($i = 0; $i < count(explode(",", $this->overheadQuantities, -1)); $i++) if (!$this->hasExteriorWallLight()) // does not have wall light $value += (floor($this->getOverheadDoorWidths($i) / 3) - 2) * $this->getOverheadDoorQuantities($i); for ($i = 0; $i < count(explode(",", $this->slidingQuantities, -1)); $i++) if (!$this->hasExteriorWallLight()) // does not have wall light $value += (floor($this->getSlidingDoorWidths($i) / 3) - 2) * $this->getSlidingDoorQuantities($i); for ($i = 0; $i < count(explode(",", $this->biFoldQuantities, -1)); $i++) if (!$this->hasExteriorWallLight()) // does not have wall light $value += (floor($this->getBiFoldDoorWidths($i) / 3) - 2) * $this->getBiFoldDoorQuantities($i); if (!$this->hasExteriorWallLight()) // if it doesn't have exterior wall light $value += $this->getTotalQuantityBuildingProduct(self::eveAccent, $showInsulation, $showPerma) + $this->getTotalQuantityBuildingProduct(self::gableAccent, $showInsulation, $showPerma); $quantities[] = (ceil($this->getBuildingWidth() / 3) + ceil($this->getBuildingLength() / 3)) * 2 + 1 - floor($this->getLengthExteriorWallLight() / 3) - $value; $quantity = 0; $value = 0; for ($i = 0; $i < count(explode(",", $this->overheadQuantities, -1)); $i++) if ($this->hasExteriorWallLight()) // has wall light $value += (floor($this->getOverheadDoorWidths($i) / 3) - 2) * $this->getOverheadDoorQuantities($i); for ($i = 0; $i < count(explode(",", $this->slidingQuantities, -1)); $i++) if ($this->hasExteriorWallLight()) // has wall light $value += (floor($this->getSlidingDoorWidths($i) / 3) - 2) * $this->getSlidingDoorQuantities($i); for ($i = 0; $i < count(explode(",", $this->biFoldQuantities, -1)); $i++) if ($this->hasExteriorWallLight()) // has wall light $value += (floor($this->getBiFoldDoorWidths($i) / 3) - 2) * $this->getBiFoldDoorQuantities($i); $quantity += $this->getQuantityExteriorWallLight() - $value; $quantityGableAccents = $this->getQuantityBuildingProduct(self::gableAccent, $showInsulation, $showPerma); if ($this->hasExteriorWallLight()) // if it has exterior wall light $quantity -= $this->getTotalQuantityBuildingProduct(self::eveAccent, $showInsulation, $showPerma) + $quantityGableAccents[0]; $quantities[] = $quantity; break;
  24. As far as I can understand what you're saying, I may have explained it incorrectly. The quote page has about 60 different inputs for changing things like: - building width - building height - building length - building type (residential, commercial, barn, hayshed....) - insulated or not - how many windows? - how many doors? - what's the roof pitch? The sales guy will sit down with a customer and enter in all that information and right next to the input boxes there is a live quote which displays the actual live price for those options. That price is calculated by running through the quantities of every single available building product (300 of them), getting the unit price and finally getting a final cost for that job, down to the penny. It's so accurate that I know that building will require 14,394 screws to complete, not 1 more, not 1 fewer. So I don't think I can do it your way (please tell me if I'm wrong) because I don't have parent items and sub-items, I just have inputs. If the sales guy makes the building 10 feet longer, the program needs to recalculate every quantity because that might change the quantities, lengths, widths and heights of 20-30 different items (lumbers, metals, trims, posts, more labour.....). So they're not just choosing to add more corner mouldings, they're changing the building dimensions and that is getting a new quantity for corner mouldings on the back end.
  25. Every time an input box is edited on the quote page, the pricing for the entire job is recalculated, that means recalculating every quantity of every product, building the HTML for the quote and displaying it on the page using AJAX. So if the customer wants 10 gable stops instead of 5, you make that change and the program recalculates every single quantity of every product, every length, height, width, recalculates the cost of that job and displays it. It's taking about 10 seconds where before it was almost instant with individual functions for each call. I'm actually getting complains from the sales guys that it's taking so long to update now after a change. So to answer your question, there is no time when I would only be calling corner moulding or ceiling-only labour, every single building product is recalculated and called on any edit. When the sales guys are sitting with a customer, the customer likes to change 10-20 different things to try and get the price within their range. They might add a window and that will change the quantities of 5 or 6 different lumber products used in framing the window, it'll remove quantities of exterior metal and add window labour costs so the entire building needs to be recalculated when this change is made. No, I was not using variable functions, that was the reason for the change. I had actual functions created and named for every single item quantity, width, length, height, unit-price and total price. It was a huge pain adding a new product and entering functions for every dimension calculation, then adding that to the total price of the building price calculation. That's a good idea to change all the items to constants though, I'll try doing that. Right now I have all the building products in the database with a row ID and then defined in the program like so: private $lumber2x8x12Treated = 14; private $lumber2x8x16Treated = 15; private $lumber2x6x12 = 16; private $lumber2x6x16 = 17; private $lumber2x8x12 = 18; private $lumber2x8x16 = 19; private $lumber2x4x12 = 20; private $lumber2x4x16 = 21; private $lumber2x10x16 = 23; private $lumber2x6x16TreatedFillerBoard = 24; private $lumber2x6x12TreatedFillerBoard = 25; private $lumber2x8x16TreatedFillerBoard = 26; private $lumber2x8x12TreatedFillerBoard = 27; private $lumber2x6x12Treated = 32; private $lumber2x6x16Treated = 33; private $wallMetal = 34; private $gableMetal = 42; private $roofMetal = 43; private $wallScrews = 44; private $trimScrews = 46; private $heelMetal = 47; private $biFoldDoorMetal = 48; private $slidingDoorMetal = 49; private $exteriorBaseTrim = 50; private $birdStop = 51; private $ridgeCap = 52; private $ridgeLight = 53; As for the post right above this one, I'll reply to that once I read it again and figure it out a bit better, I just ran through it quickly but I'm heading to bed here and need some more time to read through it a bit better. I will reply to it when I get a chance.
×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.