Announcement

Collapse
No announcement yet.

Product Minimum Quantities In Memorium

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    Product Minimum Quantities In Memorium

    My heart sunk when I learned of Bill Weiland's passing. For many of us he was a great developer with great customer service. For me, he was an inspiration.

    Early on, I struggled to learn Miva Merchant and being self-employed there was no one to turn to but the forums. Bill was always there to offer a solution and help me become a better programmer.

    Bill epitomized the selfless sharing and community building found on this forum. Bill was always the first to share information and lend a helping hand. He was always supportive and never condescending. He helped build this community that has made Miva especially different than other carts.

    With all the help that Bill gave, I too wanted to start giving back to this forum and assist others and started to post answers and solutions. I think Bill's helpfulness was infectious. I made many great personal friends from sharing on this forum.

    After the basket:groups array came out in PR8 my QMIN module broke and hasn't been updated so I wrote some code that emulates the functionality of the QMIN module.

    So in Bill's memory and I would like to share it.

    Step 1. Create a Product Custom Field for quantity minimums

    Utilities Settings > Custom Fields > Add >
    Type: Product
    Code: qmin
    Name: Qmin
    Field Type: Text

    Step 2. Populate Product Qmin data

    Products > Custom Fields > Qmin
    The data is pipe separated with the data mask of minimum|step1,step2,step3,etc|maximum|. For example, if you sell a product in kits of 100 up to 500 then enter the data 100|100,200,300,400,500|500|. If there is no product minimum then just leave the field blank.


    Step 3. Create a page template named Qmin for the quantity select box found on the PROD page.

    User Interface > Pages > Add >
    Name: Qmin
    Description: Qmin quantity select box

    Code:
    <mvt:if expr="'PROD' CIN g.Screen">
        <mvt:if expr="NOT ISNULL l.settings:product:customfield_values:customfields:qmin">
        <mvt:assign name="g.has_qmin" value="1" />
            <mvt:assign name="g.qminimum" value="gettoken(l.settings:product:customfield_values:customfields:qmin, '|', 1)" />
            <mvt:assign name="g.qsteps" value="gettoken(l.settings:product:customfield_values:customfields:qmin, '|', 2)" />
            <mvt:assign name="g.qmaximum" value="gettoken(l.settings:product:customfield_values:customfields:qmin, '|', 3)" />
            <mvt:if expr="NOT ISNULL g.qsteps">
                <mvt:assign name="l.settings:qsteps" value="miva_array_serialize (g.qsteps)" />
                <mvt:assign name="l.settings:qsteps_array" value="miva_array_deserialize( l.settings:qsteps )" />
                    <select name="Quantity">
                    <mvt:foreach iterator="qstep" array="qsteps_array">
                        <option value="&mvte:qstep;">&mvte:qstep;</option>
                    </mvt:foreach>
                    </select>
            <mvt:elseif expr="g.qminimum">
                <input type="text" name="Quantity" value="&mvte:global:qminimum;" size="4">
            <mvt:else>
                <input type="text" name="Quantity" value="1" size="4">
            </mvt:if>
        <mvt:else>
        <input type="text" name="Quantity" value="1" size="4">
        </mvt:if>
    <mvt:elseif expr="'BASK' CIN g.Screen">
    <mvt:item name="customfields" param="Read_Product_Code( g.selected_code, 'qmin', g.qmin_customfield )" />
        <mvt:if expr="NOT ISNULL g.qmin_customfield">
            <mvt:assign name="g.has_qmin" value="1" />
            <mvt:assign name="g.qminimum" value="gettoken(g.qmin_customfield, '|', 1)" />
            <mvt:assign name="g.qsteps" value="gettoken(g.qmin_customfield, '|', 2)" />
            <mvt:assign name="g.qmaximum" value="gettoken(g.qmin_customfield, '|', 3)" />
            <mvt:if expr="NOT ISNULL g.qsteps">
                <mvt:assign name="l.settings:qsteps" value="miva_array_serialize (g.qsteps)" />
                <mvt:assign name="l.settings:qsteps_array" value="miva_array_deserialize( l.settings:qsteps )" />
                    <select name="Quantity">
                    <mvt:foreach iterator="qstep" array="qsteps_array">
                        <mvt:assign name="g.qstep_index" value="g.qstep_index + 1" />
                        <option value="&mvte:qstep;"<mvt:if expr="l.settings:qstep EQ g.selected_quantity"> selected</mvt:if>>&mvte:qstep;</option>
                    </mvt:foreach>
                    </select>
            <mvt:else>
                <input type="text" name="Quantity"  size="4" value="&mvt:global:selected_quantity;" />
            </mvt:if>
        <mvt:else>
            <input type="text" name="Quantity"  size="4" value="&mvt:global:selected_quantity;" />
        </mvt:if>
    <mvt:else>
        <input type="text" name="Quantity" value="1" size="4">
    </mvt:if>
    Add Items: Buttons, Custom Fields, Product, Product Display, Product Attributes

    In the Product Display Tab select and add the custom field Qmin.

    Step 4. Create a page template named PREACTION_QTYG

    Code: PREACTION_QTYG
    Description: Preaction on Basket page to error check Update Quantity form

    Code:
    <mvt:if expr="'QTYG' CIN g.Action">
    <mvt:item name="customfields" param="Read_Product_Code( g.selected_code, 'qmin', g.qmin_customfield )" />
    <mvt:else>
    <mvt:item name="customfields" param="Read_Product_Code( g.product_code, 'qmin', g.qmin_customfield )" />
    </mvt:if>
        <mvt:if expr="NOT ISNULL g.qmin_customfield">
            <mvt:assign name="g.has_qmin" value="1" />
            <mvt:assign name="g.miva_separator" value="'|'" />
            <mvt:assign name="g.qminimum" value="gettoken( g.qmin_customfield, g.miva_separator, 1 )" />
        </mvt:if>
    
    <mvt:if expr="g.quantity LT g.qminimum">
        <mvt:assign name="g.quantity" value="g.qminimum" />
        <mvt:assign name="g.error_message_count" value="g.error_message_count + 1" />
        <mvt:assign name="g.error_messages[1]" value="'This item has a minimum quantity.'" />
        <mvt:assign name="g.formerror" value="1" />
    </mvt:if>
    Assign the item Custom Fields

    Step 5: Update PROD template

    This will insert the quantity minimum in the text box.

    On the PROD > Product Display template find the form input for the quantity and replace with:

    Code:
    <div class="product-quantity">
        <span>Quantity:</span><mvt:do name="l.result" file="g.Module_Feature_TUI_MGR" value="TemplateManager_Render_Page( 'QMIN' )" />
    </div>
    Step 6: Update BASK template

    This will do a preaction on the update quantity form to make sure the user doesn't enter a quantity lower than the minimum.

    On the BASK > Basket Contents tab:

    Find the basket:groups array iterator and add just below:

    Code:
    
    <mvt:foreach iterator="group" array="basket:groups">
    //
    <mvt:comment>Create global variables for QTYG Preaction quantity minimums</mvt:comment>
    <mvt:comment>Preaction checks and adjusts for quantity minimums in product:custom_fields:qmin</mvt:comment>
    <mvt:assign name="g.selected_quantity" value="l.settings:group:quantity" />
    <mvt:assign name="g.selected_code" value="l.settings:group:code" />
    Find the Update Item Quantity Form and add hidden inputs:

    Code:
    <form method="post" action="&mvte:urls:BASK:auto;">
    //
    <mvt:comment>Preaction checks and adjusts for quantity minimums in product:custom_fields:qmin</mvt:comment> 
    <input type="hidden" name="PreAction" value="PREACTION_QTYG">
    <input type="hidden" name="Action" value="QTYG">
    <input type="hidden" name="selected_code" value="&mvte:group:code;">
    Find the Update Item Quantity Input Box and replace:

    Code:
    //
    ​<mvt:comment>Screen checks and adjusts for quantity minimums in product:custom_fields:qmin</mvt:comment>
    <mvt:do name="l.result" file="g.Module_Feature_TUI_MGR" value="TemplateManager_Render_Page( 'QMIN' )" />
    <button type="submit" class="">Update</button>
    </form>
    Add Items > Custom Fields

    This is custom code so may not work in every merchant store but you are welcome to try this code and fork it to your taste. This code is for technically minded merchants and may break your store. Future Miva updates may also break this code.

    Note: I didn't have user privileges in the Community News section so I posted the memorium here.

    http://www.alphabetsigns.com/

    #2
    Thank you.
    Thanks,

    Rick Wilson
    CEO
    Miva, Inc.
    [email protected]
    https://www.miva.com

    Comment


      #3
      Hello Alphabet,

      Thanks for your heartfelt posting and subsequent coding.

      I had not know about Bill's passing until I found this thread and, of course, I was surprised and saddened. Like many here, Bill was a great help to me and a real gentleman in the way he developed and provided modules for the growing Miva platform and community. We had met several times at MivaCon so it was always good to thank him personally.

      I appreciate you posting this code which I have applied to my site. I am, however, wondering about your Step 2 when it is a product with a minimum quantity, with no kits and no maximum. Just minimum quantity. I've played with the following, to no avail:

      12||| and
      12||999|

      It appears that it initially works on the product page (i.e. showing 12 in the quanity box) but I'm able to reduce that number and Add to Cart without getting an error message. Additionally, I can reduce the quantity in the Cart down to 1 if I like. Again, no errors.

      Does your code allow for this scenario?

      Many thanks again.

      cheers,
      Michael

      Comment


        #4
        Hi Michael,

        On my site's PROD page you can change the quantity text input to a value less than the minimum and submit.

        But when it adds to the basket (Action=ADPR Screen=BASK) then an error is displayed on the BASK page and the basket:groups quantity is rewritten to the minimum.

        You will need to display the g.error_messages array on the BASK page:
        Code:
            <mvt:if expr="g.error_message_count">     <div class="row">         <mvt:foreach iterator="error_message" array="global:error_messages">         <div class="col-sm-12 text-danger">&mvt:error_message;</div>         </mvt:foreach>     </div>    </mvt:if>
        The PREACTION_QTGY adds the g.error_message and also throws a g.formerror so the user shouldn't be able to get to the OCST.
        http://www.alphabetsigns.com/

        Comment


          #5
          To get the error messages from one page to another I had to use a global variable.

          On the BASK page you can merge the global error_messages array with the local l.settings:messages:error_messages.

          Code:
              <mvt:if expr="g.error_message_count">
                  <mvt:assign name="g.global_error_message_count" value="miva_array_collapse( g.error_messages )" />
                  <mvt:assign name="g.local_error_message_count" value="miva_array_collapse( l.settings:messages:error_messages )" />
                  <mvt:assign name="g.has_error_messages_array" value="miva_array_merge_ref( g.error_messages, 1, g.global_error_message_count, l.settings:messages:error_messages, g.local_error_message_count )" />
                  <mvt:assign name="l.settings:messages:error_message_count" value="miva_array_elements( l.settings:messages:error_messages )" />
              </mvt:if>
          So now you won't have to iterate through two error message arrays.

          http://www.alphabetsigns.com/

          Comment


            #6
            Hi Alphabet,

            Thanks very much for the extra code for errors. Seems, however, I'm still having troubles.

            1. Do you have an example on your site where you have a minimum quantity but no "kits"?

            2. In that case, what is the format in the qmin custom field?

            Hopefully I can revisit this with fresh eyes tomorrow! Thanks.

            cheers,
            Michael

            Comment


              #7
              I sent you a PM.

              http://www.alphabetsigns.com/

              Comment


                #8
                Hi had no idea that Bill had passed until I saw this thread. He will be missed. Truly.

                Comment


                  #9
                  This is excellent and much appreciated coding. Thank you for sharing. Bill will definitely be very missed. He was an inspiring developer.

                  Comment

                  Working...
                  X