Jump to content

DeX

Members
  • Posts

    258
  • Joined

  • Last visited

Everything posted by DeX

  1. Another slight addendum, what about for items that do not rely on quantities of other items but rely solely on inputs from the salesman? I see the rules in these examples are for multipliers and offsets used in conjunction with quantities of other existing items but what about things like gable vents which have a quantity input by the sales person on the quote? The quantity of these items is simply the exact number input by the salesman. Nothing more. Most importantly I don't see how the interface would work for this. The input fields are hard coded on the input page, I don't have a list in the database. So for the interface to allow the user to add a new product into the system and base it on a salesman input, that would be quite difficult. I would need to shift all inputs to the database and categorize / order them for how they would display relative to one another.
  2. To test what you're receiving on your ajax.php page, you can print it out with the following somewhere on the page: print_r($_POST); To test and see if your database insert is working at all, try replacing the POST variables with static entries. Once you narrow down where the error is, work on it from there.
  3. Well today is the day I actually start implementing this change in the code and I'm scanning which items I can apply this to and which I can't. I keep focusing on the ones that check to see if the item (door or window) is customer supplied or not and how that would translate. You mentioned above that I could use a multiplier of 1 or 0 to accomplish this but would this be better than separating the customer supplied doors and non-customer supplied doors into 2 separate items? Here is one I'm specifically dealing with right now: case (self::sideWallBeam) : for ($i = 0; $i < count(json_decode($this->overheadQuantities, true)); $i++) if (strtolower($this->getOverheadDoorLocations($i)) == strtolower("Side Wall")) $quantities[] = $this->getOverheadDoorQuantities($i); for ($i = 0; $i < count(json_decode($this->slidingQuantities, true)); $i++) if (strtolower($this->getSlidingDoorLocations($i)) == strtolower("Side Wall")) $quantities[] = $this->getSlidingDoorQuantities($i); break; The salesman enters two 10x12 overhead doors, another 3 10x10 overhead doors and finally a single 10x12 sliding door when doing the quote. For each group of overhead doors, I check to see if that door location is side-wall or end-wall (chosen by salesman) and then add side-wall beams accordingly. My main confusion here resides with the number of options available when adding these doors. They can be customer supplied, end-wall, side-wall and also insulated / non-insulated. Various items depend on each of these attributes when determining if they are required for building the building. Thanks again.
  4. When adding doors, it is always a set number of inputs and they're always the same. The same options are available for every door. Then there are different input options for windows but they're always the same for each window. Then the same for a few other items with a total of about 10 different items like this.
  5. I have a quoting system that some of you may be familiar with from my previous questions, this is another piece of it I'm trying to clean up. The user can add a door or window to the quote and can also associate options with the item. For example, they can add the door, then supply the type of opening mechanism (chain, motor....), then how many windows are in the door, then which storey the door will be installed on. Then they can add another door if they wish. Currently I'm using a jQuery popup like a lightbox (Bootstrap modal dialog) to ask the user all of the proper questions about the door, then when they click the button to save the door, I'm serializing all of the inputs from that lightbox and assigning them to a hidden variable farther down the page. No matter how many doors they add, it all gets serialized into a JSON array into that hidden variable and that variable is submitted to the next page to be saved to the database when the user saves the quote. I know of no other way of transferring all of this data to the next page other than collecting, serializing and submitting as a JSON array. Am I doing it correctly? Thanks.
  6. Actually that code should be this. <div class="row paginate"> <div class="col-12"> <nav> <?php // loop through 5 page numbers for ($i = 1; $i < 6; $i++) { // output initial links and set the page number in a URI variable echo '<a href ="index.php?page=' . $i . '"'; // check URI variable to see if it iss equal to our current iteration count if ($_GET['page'] == $i) echo ' class = "active" '; // output end of link echo '>' . $i . '</a>'; } ?> </nav> </div> </div>
  7. <div class="row paginate"> <div class="col-12"> <nav> <?php // loop through 5 page numbers for ($i = 1; $i < 6; $i++) { // output initial links and set the page number in a URI variable echo '<a href ="index.php?page=' . $i . '"; // check URI variable to see if it iss equal to our current iteration count if ($_GET['page'] == $i) echo ' class = "active" '; // output end of link echo '>' . $i . '</a>'; } ?> </nav> </div> </div> Untested but here is how you would build the pages dynamically. Eventually I would have the photo links in a database and I would look into using mod_rewrite with a .htaccess file so you can have the following: .../photos/2 instead of: .../index.php?page=2
  8. I took a closer look at how the constructor is building the array of information and it doesn't appear to be the database calls, there are actually very few here. Here is the flow of how the array is built: - a database call is made to get all product prices and stored for future use (see farther down) - a database call is made to get all the product names and ID - a foreach loop is run on each product ID and inside the loop..... -- the product ID is passed to a function which has a large switch statement with a quantity calculation for each product ID. It finds the matching product ID, runs through the code to get the quantity (based on what the DOM element inputs are) and returns the quantity in an array (see why below) -- the same for the product widths (separate function) -- the same for lengths -- the same for heights -- then it gets the total quantity of the product. This is because the user could have entered 2 10x12 doors and 5 10x10 doors. It will get the 2 quantities individually in the previous step and the total quantity will be 7. -- then it gets the price of the product from the price array above -- then it gets the total price for the product, based on the other attributes and a multiplier by the unit price That's it, I've run the SQL queries individually and they all return instantly, but since it's running all of this individually on 360 products, it takes 4 seconds to complete. I have put an echo statement with a timer after each cycle and it gradually gets up to 4 seconds after running for all 360 products in the database. If you're asking why I can't get all of this information with a single call from the database, it's because the information isn't in the database. The user is entering data on the page to generate the quote and the quote is built entirely from the inputs the user has entered, with minimum database calls to get things like the unit prices of each product. I plan on using a rules system to build the quantity calculations for the products as some of you have helped me with in another thread but that change is being saved for after I complete this object oriented conversion I have going here.
  9. Moneris would have taken 3 weeks and a credit check to set up. Went with PayPal to meet the project deadline.
  10. Yes, the quote object is needed in entirety only on the Ajax call when the quote is being generated, which happens any time an input field is modified on the quote page. So reading through the answers is it correct to say that I can keep the large object creation in the constructor and I need to look into maybe indexing more tables in the database to speed up the query? I do need all the object variables somewhere on the quote page.
  11. Got it working by saving the listing prior to payment and activating the payment using PayPal's notify_url to pass back the property ID to be activated. Thanks for helping me out with the logic flow.
  12. You should be using opposing quotes when nesting, try switching to an apostrophe ( ' ) around all your $content data instead of double quotes ( " ). That might be part of your problem. Also these PDF generators don't like malformed HTML code do any mistake at all will corrupt the output. I can see where it's doing the PDF generation here: require_once(dirname(__FILE__).'/html2pdf/html2pdf.class.php'); $html2pdf = new HTML2PDF('P','A4','fr'); $html2pdf->WriteHTML($content); $html2pdf->Output('exemple.pdf'); You're passing in your HTML code through your $content variable and then attempting to save it to example.pdf inside the current directory. Does your webserver have permissions to save into that directory? Should you be trying to save into a different directory? If it still doesn't work, try passing in the most basic HTML you can think of and see if that works, then keep working up your $content variable by continuously adding pieces to it until you get to either: a) a working code sample using your entire $content piece. ----or----- b) the specific line that breaks your PDF generator. Try this to see if it works: require_once(dirname(__FILE__).'/html2pdf/html2pdf.class.php'); $html2pdf = new HTML2PDF('P','A4','fr'); $html2pdf->WriteHTML("<html><body>Hello</body></html>"); $html2pdf->Output('exemple.pdf'); If that doesn't work then your issue is somewhere further back in the code. Or if by "doesn't work" you mean that it doesn't save the PDF,, then you likely don't have write permissions in the directory where you're trying to save the example.pdf which here is your current directory and I can tell you now that would be an enormous security risk. I cringe at the thought of it.
  13. Thank you, I will switch it to store the information prior to payment and set the flag on payment success. If the session can't be edited in any way then I won't worry about it. I can even pass the database row ID to Paypal and get it back from them after payment so it doesn't have to go into the session. I think I can do that.
  14. My application is completely working, I'm simply wondering about how the flow should work. I have a PHP site where: 1. The user chooses 1 of 2 possible listing types to list their property for rent. Whichever they choose is stored in a session variable and they're redirected to page 2. 2. Here they fill out their rental property information, click a submit button and all entered information (once validated) is entered into a session variable with the listing type from page 1. They are now redirected to page 3. 3. Page 3 only has a button to click to be redirected to PayPal for payment. The only reason I don't have this button on page 2 is because I first had to get all the entered information into the session variable and I needed an action trigger in order to accomplish this, like them clicking the submit button. I don't know if I should combine the 2 or keep this third page with just the payment button, however it does give the opportunity for the user to view their entry and confirm it is all correct prior to paying. 4. They get redirected to PayPal, pay, then are redirected back to my site with either a success or failure message. If success, a PHP function runs (triggered by function passed through URL) and saves all listing information into the database as a successful purchase and pushes the listing live. Is this a proper use of session variables and should I instead be accomplishing this some other way? Should I be saving all the listing information after page 2 and instead just be putting the database row ID into the session variable, and then setting the row's PAID flag to 1 if the payment is successful? Then it's live once the flag is set? What if someone tries to use session injection in order to bypass the PayPal payment and just manuall put their information into the database? Is this possible?
  15. This might be an issue with semantics but PHP only runs on the server and you want a PDF of data available on the client. The idea of PHP is it is capable of generating and outputting HTML to the client, or handing it off to any number of PDF generators in HTML format. PHP itself doesn't display anything, it generates HTML in order to accomplish this. So once you have the HTML generated with PHP (all those echo statements and table elements you have there), then you pass it into FPDF and FPDF will then generate your required PDF document which you can save somewhere on the server. I use DOMPDF but it's based on the same base code as MPDF and FPDF are. They're all essentially the same. When I was first learning PHP, this took me over 6 months from start to finish to accomplish but now it's used every day.
  16. They are not stored in the session. Their scope is the page they're created on and that's it. Is this a good thing or bad thing?
  17. I seem to have slowed down my system dramatically here by attempting to move everything into objects. Previously I had a setup where the view would create the quote layout and would request any data it needed from the model. So any time it needed a quantity or cost of an item to show on the quote, it would go to the model and the model would actively go to the database and fetch it whenever asked. I have attempted to move away from this on-the-fly requesting from the database and figured it would be better to have the model fetch all of that information in the constructor and make it available whenever a "quote" object is created. I would then create the "quote" object at the beginning of the quote generation process in the view and any time I needed information relating to the quote, I would simply access it by: $this->quoteDetails = $this->quoteModel->getDetails(); // gets large array which was built in constructor echo $this->quoteDetails[$productId]['quantity']; ----- or ----- echo $this->quoteDetails[$productId]['unit_price']; From there I can access any of the product attributes (price, quantity, length....) or I can access any of the information the salesman entered when doing the quote: echo $this->quoteDetails['inputs']['customer-email']; The quote is refreshed through Ajax any time a field is changed and it used to take 1 second to fetch the new quote, now it's taking about 6 seconds for obvious reasons. Is this the wrong way to go about this?
  18. case (self::whiteCaulking) : $unit_rules = array(); // note: this example is for categories, not individual items, though you could mix them easily by adding an indicator to the defining array if the $key it a category or an item and call the appropriate method to get the correct quantity $unit_rules['ManDoors'] = array('mult'=>.75,'offset'=>0); $unit_rules['Windows'] = array('mult'=>.75,'offset'=>0); $group_rules = array(); $group_rules[] = array('operation'=>'function','name'=>'ceil'); $quantity = 0; // apply any unit rules foreach($unit_rules as $key->$rule) { $quanity += ($this->getTotalQuantityByCategory($key) * $rule['mult']) + $rule['offset']; } // apply any group rules foreach($group_rules as $rule) { switch($rule['operation']) { case 'function': $quantity = $rule['name']($quantity); break; } } $quantities[] = $quantity; break; Now that I have a chance to go through this very slowly and understand it I have a few questions about the flow of the logic. 1. The switch statement checks if we're looking for caulking and then enters into this logic to get the quantity. 2. What do you mean about this example being for categories and not for items? It seems like it would work for white caulking as it is. 3. I see you've added a multiplier and an offset for 2 other items (doors / windows), I understand that. 4. I see you add a group rule of rounding up on the screws to be used later, I get that. 5. Then you execute the unit rules, this part I kind of understand. You're passing in 'ManDoors' as the key for the calculation, would it be correct to assume I should pass in the database ID of the product instead? Is that better practice? 6. In the same section, you're adding the offset, should you be multiplying by it instead? Is this a typo? 7. If I want to apply the calculation only if the door is insulated, would I just use a second offset? Would I just keep adding offsets for any additional attributes I wanted to check for like this? For example, a height labour charge is added if the building is over 16 feet high because the crew has to rent a scissor lift to do the work and that cost has to get passed to the customer. So I'm assuming I would have an offset for whether or not the building is over 16 feet. 8. Do I hard code what these offsets are or can the client add an additional offset for a new attribute when adding items? This is great, thank you. If I can allow customers to add their own products I can set this up as a portal where clients can sign themselves up without any involvement from me and I can charge them a monthly fee for access so if you would prefer to speak on the phone and I pay you for an hour of your time, that would be fine by me. It would be nice to have it here for others to see too though.
  19. Just to clarify, I needed an image uploader tool so I decided to use this GitHub project I found. It works great with image uploads on my server except for this error I'm getting because of the .htaccess file. The error happens when I try and view the image uploaded through the tool. Commenting out the lines in the file makes everything work perfectly but I want to leave them in if they're a security measure.
  20. I need a file upload tool so I checked out the Blue Imp project on GitHub and everything works fine if I comment out all the lines in the .htaccess file. If I leave the lines in, I get an error when trying to view the file on my server. Commenting them out allows me to view the file no problem. Here is the error I get when I leave the .htaccess file alone: Here is the .htaccess file, the default file that came with the project: # The following directives prevent the execution of script files # in the context of the website. # They also force the content-type application/octet-stream and # force browsers to display a download dialog for non-image files. SetHandler default-handler ForceType application/octet-stream Header set Content-Disposition attachment # The following unsets the forced type and Content-Disposition headers # for known image files: <FilesMatch "(?i)\.(gif|jpe?g|png)$"> ForceType none Header unset Content-Disposition </FilesMatch> # The following directive prevents browsers from MIME-sniffing the content-type. # This is an important complement to the ForceType directive above: Header set X-Content-Type-Options nosniff # Uncomment the following lines to prevent unauthorized download of files: #AuthName "Authorization required" #AuthType Basic #require valid-user I first tried it with a file named 035.JPG and I thought maybe it had a problem with the file extension so I tried it again with uploading 035.jpg. That didn't work so I tried again with a different image named studio.png (Android Studio logo) and they all act the same. All files are very small thumbnails. My goal here is to keep the security of the file but allow my users to view the images they upload.
  21. The quantity of screws is based on the width of the sliding doors though, because there is a screw every so many square feet I believe. And then another set around the edge, something along those lines, I know the calculation I posted is the calculation we're using in production right now.
  22. Very cool, thank you! When the user is adding the new item and trying to input how the quantity calculation will work, how could the interface work for that? How could the specify that 3/4 of a tube of this new product needs to be added any time another product (doors / windows) is added? And to make it more complicated, what about all the confusion for how the user would enter the calculation for the Sliding Tec Screws? Would I just ask them for the multiplier, offset and rules for each product?
  23. I currently have a rather large PHP system where salesmen enter building details into a form and it builds a bill of materials (BOM) based on their inputs. Currently if they want to add any new materials into the system I have to do it because the calculations for getting the quantities of each item often depend on the attributes of other items in the system and I don't know how to give this control to the user. For example, when the quote is generated to calculate the BOM, it iterates over each material in the database and fetches the quantity calculation based on the ID. The quantity calculation is hard coded into the PHP and could be something like this: case (self::slidingTecScrews) : $quantity = 0; $buffer = 1.03; $screwsPerBox = 500; for ($i = 0; $i < count(json_decode($this->slidingQuantities, true)); $i++) $quantity += ($this->getSlidingDoorWidths($i) / 2 + 1) * $this->getSlidingDoorQuantities($i) * 5 * ceil($this->getSlidingDoorWidths($i) / 3) * $this->getSlidingDoorQuantities($i); // for all doors $quantity *= $buffer; // add buffer for extra screws if ($quantity > 0) $quantity += $screwsPerBox - ($quantity % $screwsPerBox); // round up to nearest full box $quantities[] = floor($quantity); break; In this example I get the quantity of Sliding Door Tec Screws and I run a calculation of how many I need per sliding door, then multiply it by the quantity of sliding doors to get the total. Then I add in a buffer because the crew is always dropping some on the ground, then I round it up to a full box. I have absolutely no idea how I would build an interface to allow one of the users to add in a product and assign this calculation for the quantity. For good measure here's another random quantity calculation: case (self::whiteCaulking) : $quantity = ceil(( $this->getTotalQuantityManDoors(true) + $this->getTotalQuantityWindows(true)) * .75 ); $quantities[] = $quantity; break; This one passes a variable into the quantity of doors / windows to specify whether or not it should include customer supplied doors into the calculation. Sometimes the door is added to the quote but the customer may want to supply it themselves and therefore we need to order the extra trims (and white caulk) but don't want to factor the door into the total material pricing. Here we use 3/4 of a tube of caulking per door / window. Sometimes it will use the quantity of doors in the calculation but only if they are insulated, or only if they're more than 12 feet high. Sometimes it'll add a product based on every 10 square feet of wall light in a building, it could be based on almost anything. Getting the quantity and per-item cost of everything in the BOM allows me to show the actual build cost for the structure and then apply a markup to get the selling price. Thanks a lot.
  24. I don't even know where to start, I see each one has its own pricing but what else do I look for? If I choose Paypal, am I able to have a custom payment layout without Paypal branding on it? The site I'm building is a completely custom site where people can list their homes for rent and there will be two types of rental list options. Here are the requirements for my gateway: - website only, no local point of sale transactions - only 2 different items for sale (2 types of rentals) - need to accept VISA and Master Card - until we expand into other countries, all customers will be from Canada - need to be able to use a completely custom interface that I'm building myself I think that's it. Thanks a lot, I've been looking at lots of solutions and can't figure out which one I should use. Paypal looks easy but the price is high.
×
×
  • 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.