Plugin Directory

Changeset 3374381


Ignore:
Timestamp:
10/07/2025 12:29:20 PM (6 months ago)
Author:
techspawn1
Message:

Release 1.1.0: Added Location Selection & Smart Stock Updates Feature

Location:
multiloca-lite-multi-location-inventory/trunk
Files:
5 added
5 deleted
12 edited

Legend:

Unmodified
Added
Removed
  • multiloca-lite-multi-location-inventory/trunk/admin/css/multiloca-lite-admin.css

    r3336945 r3374381  
    143143.multiloca-preview-container h3 {
    144144    margin-top: 0;
     145}
     146
     147/* Maintenance section styling */
     148.multiloca-maintenance-section {
     149    padding: 20px;
     150    background: #fff;
     151    border: 1px solid #ddd;
     152    border-radius: 4px;
     153}
     154
     155.maintenance-tool {
     156    padding: 20px;
     157    background: #f9f9f9;
     158    border: 1px solid #e0e0e0;
     159    border-radius: 4px;
     160    margin-bottom: 15px;
     161}
     162
     163.maintenance-tool h3 {
     164    margin-top: 0;
     165    color: #333;
     166}
     167
     168.maintenance-tool p {
     169    color: #666;
     170    margin-bottom: 15px;
    145171}
    146172
  • multiloca-lite-multi-location-inventory/trunk/admin/partials/multiloca-lite-custom-inventory-fields.php

    r3336945 r3374381  
    110110                    '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    111111               
    112                 echo '<div class="multiloca-lite-location-expanded-item">';
     112                echo '<div class="multiloca-lite-location-expanded-item ' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    113113                echo '<div class="multiloca-lite-location-header">';
    114114                echo '<h4><span class="multiloca-toggle-icon">+</span> ' . esc_html($location->name) . '</h4>';
     
    222222                    '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    223223               
    224                 echo '<tr class="' . esc_attr($stock_class) . '">';
     224                echo '<tr class="' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    225225                echo '<td>' . esc_html($location->name) . '</td>';
    226226                echo '<td>';
     
    308308                    '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    309309               
    310                 echo '<li class="' . esc_attr($stock_class) . '">';
     310                echo '<li class="' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    311311                echo '<span class="location-name">' . esc_html($location->name) . '</span>: ';
    312312                echo wp_kses_post($stock_text);
     
    389389                    '<span class="stock-label out-of-stock">' . esc_html($outofstock_text) . '</span>';
    390390               
    391                 echo '<div class="multiloca-lite-location-text ' . esc_attr($stock_class) . '">';
     391                echo '<div class="multiloca-lite-location-text ' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    392392                echo '<div class="location-header">';
    393393                echo '<span class="location-name">' . esc_html($location->name) . '</span>';
     
    476476                    '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    477477               
    478                 echo '<div class="multiloca-lite-location-card ' . esc_attr($stock_class) . '">';
     478                echo '<div class="multiloca-lite-location-card ' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    479479                echo '<div class="card-header">';
    480480                echo '<div class="location-name">';
  • multiloca-lite-multi-location-inventory/trunk/admin/partials/multiloca-lite-settings.php

    r3336945 r3374381  
    2424
    2525        <input type="radio" name="ml-tabset" id="ml-tab3" aria-controls="ml-panel3">
    26         <label for="ml-tab3"><?php esc_html_e('Documentation', 'multiloca-lite-multi-location-inventory'); ?></label>
     26        <label for="ml-tab3"><?php esc_html_e('Maintenance', 'multiloca-lite-multi-location-inventory'); ?></label>
     27
     28        <input type="radio" name="ml-tabset" id="ml-tab4" aria-controls="ml-panel4">
     29        <label for="ml-tab4"><?php esc_html_e('Documentation', 'multiloca-lite-multi-location-inventory'); ?></label>
    2730
    2831        <div class="ml-panels">
     
    4548                </form>
    4649            </section>
    47             <section id="ml-panel3" class="ml-tab-panel documentation">
     50            <section id="ml-panel3" class="ml-tab-panel">
     51                <div class="multiloca-maintenance-section">
     52                    <h2><?php esc_html_e('Stock Management Tools', 'multiloca-lite-multi-location-inventory'); ?></h2>
     53                   
     54                    <div class="maintenance-tool">
     55                        <h3><?php esc_html_e('Recalculate All Stock', 'multiloca-lite-multi-location-inventory'); ?></h3>
     56                        <p><?php esc_html_e('This will recalculate WooCommerce stock quantities for all products based on their location inventory. Use this if stock totals appear incorrect.', 'multiloca-lite-multi-location-inventory'); ?></p>
     57                        <button type="button" id="wcmlim-recalculate-stock" class="button button-primary">
     58                            <?php esc_html_e('Recalculate All Stock', 'multiloca-lite-multi-location-inventory'); ?>
     59                        </button>
     60                        <div id="wcmlim-recalculate-status" style="margin-top: 10px;"></div>
     61                    </div>
     62                   
     63                    <div class="maintenance-tool" style="margin-top: 30px;">
     64                        <h3><?php esc_html_e('How Stock Calculation Works', 'multiloca-lite-multi-location-inventory'); ?></h3>
     65                        <ul style="list-style: disc; margin-left: 20px;">
     66                            <li><?php esc_html_e('WooCommerce stock quantity is automatically calculated as the sum of all location stocks', 'multiloca-lite-multi-location-inventory'); ?></li>
     67                            <li><?php esc_html_e('WooCommerce stock fields are read-only to prevent conflicts', 'multiloca-lite-multi-location-inventory'); ?></li>
     68                            <li><?php esc_html_e('Stock updates when you modify location inventory or place/cancel orders', 'multiloca-lite-multi-location-inventory'); ?></li>
     69                            <li><?php esc_html_e('Stock status (In Stock/Out of Stock) is automatically managed', 'multiloca-lite-multi-location-inventory'); ?></li>
     70                        </ul>
     71                    </div>
     72                </div>
     73
     74                <script>
     75                jQuery(document).ready(function($) {
     76                    $('#wcmlim-recalculate-stock').on('click', function() {
     77                        var $button = $(this);
     78                        var $status = $('#wcmlim-recalculate-status');
     79                       
     80                        $button.prop('disabled', true).text('<?php esc_js(_e('Recalculating...', 'multiloca-lite-multi-location-inventory')); ?>');
     81                        $status.html('<div style="color: #666;">⏳ Processing all products...</div>');
     82                       
     83                        $.ajax({
     84                            url: ajaxurl,
     85                            type: 'POST',
     86                            data: {
     87                                action: 'wcmlim_recalculate_all_stock',
     88                                nonce: '<?php echo wp_create_nonce('wcmlim_recalculate_stock'); ?>'
     89                            },
     90                            success: function(response) {
     91                                if (response.success) {
     92                                    $status.html('<div style="color: green;">✅ ' + response.data.message + '</div>');
     93                                } else {
     94                                    $status.html('<div style="color: red;">❌ Error: ' + (response.data || 'Unknown error') + '</div>');
     95                                }
     96                            },
     97                            error: function() {
     98                                $status.html('<div style="color: red;">❌ AJAX error occurred</div>');
     99                            },
     100                            complete: function() {
     101                                $button.prop('disabled', false).text('<?php esc_js(_e('Recalculate All Stock', 'multiloca-lite-multi-location-inventory')); ?>');
     102                            }
     103                        });
     104                    });
     105                });
     106                </script>
     107            </section>
     108            <section id="ml-panel4" class="ml-tab-panel documentation">
    48109                <div class="multiloca-container">
    49110                    <div class="section-title">Getting Started</div>
  • multiloca-lite-multi-location-inventory/trunk/public/class-multiloca-lite-public.php

    r3336945 r3374381  
    5757            );
    5858           
    59             // Localize script with AJAX URL
     59            // Localize script with AJAX URL and messages
    6060            wp_localize_script('multiloca-lite-public', 'multiloca_lite', array(
    6161                'ajax_url' => admin_url('admin-ajax.php'),
    62                 'nonce' => wp_create_nonce('multiloca_lite_nonce')
     62                'nonce' => wp_create_nonce('multiloca_lite_nonce'),
     63                'messages' => array(
     64                    'select_location' => __('Please select a location first.', 'multiloca-lite-multi-location-inventory'),
     65                    'stock_exceeded' => __('Quantity exceeds available stock at selected location.', 'multiloca-lite-multi-location-inventory'),
     66                    'location_selected' => __('Location selected successfully.', 'multiloca-lite-multi-location-inventory')
     67                )
    6368            ));
    6469        }
  • multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-card-view.php

    r3336945 r3374381  
    8080            '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    8181       
    82         echo '<div class="multiloca-lite-location-card ' . esc_attr($stock_class) . '">';
     82        echo '<div class="multiloca-lite-location-card ' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    8383        echo '<div class="card-header">';
    8484        echo '<div class="location-name">';
  • multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-expanded-view.php

    r3336945 r3374381  
    8080            '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    8181       
    82         echo '<div class="multiloca-lite-location-expanded-item">';
     82        echo '<div class="multiloca-lite-location-expanded-item ' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    8383        echo '<div class="multiloca-lite-location-header">';
    8484        echo '<h4><span class="multiloca-toggle-icon">+</span> ' . esc_html($location->name) . '</h4>';
  • multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-list-view.php

    r3336945 r3374381  
    8080        '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    8181   
    82     echo '<li class="' . esc_attr($stock_class) . '">';
     82    echo '<li class="' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    8383    echo '<span class="location-name">' . esc_html($location->name) . '</span>: ';
    8484    echo wp_kses_post($stock_text);
  • multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-simple-text-view.php

    r3336945 r3374381  
    8080            '<span class="stock-label out-of-stock">' . esc_html($outofstock_text) . '</span>';
    8181       
    82         echo '<div class="multiloca-lite-location-text ' . esc_attr($stock_class) . '">';
     82        echo '<div class="multiloca-lite-location-text ' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    8383        echo '<div class="location-header">';
    8484        echo '<span class="location-name">' . esc_html($location->name) . '</span>';
  • multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-table-view.php

    r3336945 r3374381  
    8686        '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>';
    8787   
    88     echo '<tr class="' . esc_attr($stock_class) . '">';
     88    echo '<tr class="' . esc_attr($stock_class) . '" data-location-id="' . esc_attr($location->term_id) . '" data-location-name="' . esc_attr($location->name) . '">';
    8989    echo '<td>' . esc_html($location->name) . '</td>';
    9090   
  • multiloca-lite-multi-location-inventory/trunk/public/css/multiloca-lite-public.css

    r3336945 r3374381  
    193193
    194194.multiloca-toggle-icon {
    195     display: inline-block;
    196     width: 20px;
    197     height: 20px;
    198     margin-right: 5px;
    199     text-align: center;
    200     line-height: 20px;
    201     font-weight: bold;
     195    font-size: 12px;
     196    margin-left: 5px;
     197    color: #666;
     198    cursor: pointer;
     199    transition: transform 0.3s ease;
     200}
     201
     202/* Location selection styles */
     203.multiloca-lite-table tbody tr,
     204.multiloca-location-item,
     205.multiloca-lite-location-card,
     206.multiloca-lite-list li {
     207    cursor: pointer;
     208    transition: background-color 0.3s ease, border-color 0.3s ease;
     209}
     210
     211.multiloca-lite-table tbody tr:not(.out-of-stock):hover {
     212    background-color: #f0f0f0;
     213}
     214
     215.multiloca-lite-table tbody tr.multiloca-location-selected {
     216    background-color: #e7f3ff;
     217    border-left: 3px solid #0073aa;
     218}
     219
     220.multiloca-lite-location-card:not(.out-of-stock):hover,
     221.multiloca-location-item:not(.out-of-stock):hover,
     222.multiloca-lite-list li:not(.out-of-stock):hover {
     223    border-color: #0073aa;
     224    box-shadow: 0 2px 8px rgba(0, 115, 170, 0.1);
     225}
     226
     227.multiloca-lite-location-card.multiloca-location-selected,
     228.multiloca-location-item.multiloca-location-selected,
     229.multiloca-lite-list li.multiloca-location-selected {
     230    border-color: #0073aa;
     231    background-color: #e7f3ff;
     232    box-shadow: 0 2px 8px rgba(0, 115, 170, 0.2);
     233}
     234
     235.multiloca-selected-location-info {
     236    background-color: #d4edda;
     237    border: 1px solid #c3e6cb;
     238    color: #155724;
     239    padding: 10px;
     240    margin: 10px 0;
     241    border-radius: 4px;
     242}
     243
     244.multiloca-message {
     245    margin: 10px 0;
     246    padding: 10px;
     247    border-radius: 4px;
     248}
     249
     250.multiloca-message.woocommerce-error {
     251    background-color: #f8d7da;
     252    border: 1px solid #f5c6cb;
     253    color: #721c24;
     254}
     255
     256.multiloca-message.woocommerce-message {
     257    background-color: #d1ecf1;
     258    border: 1px solid #bee5eb;
     259    color: #0c5460;
     260}
     261
     262.multiloca-lite-table tbody tr.out-of-stock,
     263.multiloca-lite-location-card.out-of-stock,
     264.multiloca-location-item.out-of-stock,
     265.multiloca-lite-list li.out-of-stock {
     266    opacity: 0.6;
     267    cursor: not-allowed;
     268}
     269
     270.multiloca-lite-table tbody tr:not(.out-of-stock)::after,
     271.multiloca-lite-location-card:not(.out-of-stock)::after,
     272.multiloca-location-item:not(.out-of-stock)::after,
     273.multiloca-lite-list li:not(.out-of-stock)::after {
     274    content: '🖱️ Click to select';
     275    position: absolute;
     276    top: 5px;
     277    right: 5px;
     278    font-size: 10px;
     279    color: #666;
     280    opacity: 0;
     281    transition: opacity 0.3s ease;
     282}
     283
     284.multiloca-lite-table tbody tr:not(.out-of-stock):hover::after,
     285.multiloca-lite-location-card:not(.out-of-stock):hover::after,
     286.multiloca-location-item:not(.out-of-stock):hover::after,
     287.multiloca-lite-list li:not(.out-of-stock):hover::after {
     288    opacity: 1;
    202289}
    203290
  • multiloca-lite-multi-location-inventory/trunk/public/js/multiloca-lite-public.js

    r3336945 r3374381  
    66    'use strict';
    77
     8    // Global variables for location selection
     9    var selectedLocationId = null;
     10    var selectedLocationName = null;
     11
    812    // Function to initialize on page load
    913    $(document).ready(function() {
     14        // Initialize location selection functionality
     15        initializeLocationSelection();
     16       
     17        // Initialize quantity validation
     18        initializeQuantityValidation();
     19
    1020        // Initialize expanded view functionality with event delegation
    1121        $(document).on('click', '.multiloca-lite-location-header', function(e) {
     
    3040        });
    3141    });
     42
     43    /**
     44     * Initialize location selection functionality
     45     */
     46    function initializeLocationSelection() {
     47        // Handle location row clicks for table view
     48        $(document).on('click', '.multiloca-lite-table tbody tr', function(e) {
     49            e.preventDefault();
     50           
     51            // Don't select if row is out of stock
     52            if ($(this).hasClass('out-of-stock')) {
     53                showMessage('This location is out of stock.', 'error');
     54                return;
     55            }
     56
     57            var locationId = $(this).data('location-id');
     58            var locationName = $(this).data('location-name');
     59           
     60            if (locationId && locationName) {
     61                selectLocation(locationId, locationName, $(this));
     62            }
     63        });
     64
     65        // Handle location clicks for other views
     66        $(document).on('click', '.multiloca-location-item, .multiloca-lite-location-card, .multiloca-lite-list li, .multiloca-lite-location-expanded-item, .multiloca-lite-location-text', function(e) {
     67            // Don't trigger on header clicks for expanded view
     68            if ($(e.target).closest('.multiloca-lite-location-header').length) {
     69                return;
     70            }
     71           
     72            e.preventDefault();
     73           
     74            // Don't select if item is out of stock
     75            if ($(this).hasClass('out-of-stock')) {
     76                showMessage('This location is out of stock.', 'error');
     77                return;
     78            }
     79
     80            var locationId = $(this).data('location-id');
     81            var locationName = $(this).data('location-name');
     82           
     83            if (locationId && locationName) {
     84                selectLocation(locationId, locationName, $(this));
     85            }
     86        });
     87    }
     88
     89    /**
     90     * Select a location
     91     */
     92    function selectLocation(locationId, locationName, $element) {
     93        $.ajax({
     94            url: multiloca_lite.ajax_url,
     95            type: 'POST',
     96            data: {
     97                action: 'select_location',
     98                location_id: locationId,
     99                location_name: locationName,
     100                nonce: multiloca_lite.nonce
     101            },
     102            success: function(response) {
     103                if (response.success) {
     104                    selectedLocationId = locationId;
     105                    selectedLocationName = locationName;
     106                   
     107                    // Update UI to show selected location
     108                    $('.multiloca-location-selected').removeClass('multiloca-location-selected');
     109                    $element.addClass('multiloca-location-selected');
     110                   
     111                    // Show selected location message
     112                    showSelectedLocationInfo(locationName);
     113                   
     114                    // Update quantity field max value
     115                    updateQuantityMax();
     116                   
     117                    showMessage(response.data.message, 'success');
     118                } else {
     119                    showMessage(response.data || 'Failed to select location.', 'error');
     120                }
     121            },
     122            error: function() {
     123                showMessage('Error selecting location.', 'error');
     124            }
     125        });
     126    }
     127
     128    /**
     129     * Show selected location info
     130     */
     131    function showSelectedLocationInfo(locationName) {
     132        // Remove existing selection info
     133        $('.multiloca-selected-location-info').remove();
     134       
     135        // Add selection info after the heading
     136        var infoHtml = '<div class="multiloca-selected-location-info">' +
     137                      '<strong>✓ Selected Location:</strong> ' + locationName +
     138                      ' <small>(You can click another location to change)</small>' +
     139                      '</div>';
     140       
     141        $('.multiloca-lite-inventory h3').after(infoHtml);
     142    }
     143
     144    /**
     145     * Initialize quantity validation
     146     */
     147    function initializeQuantityValidation() {
     148        // Validate quantity on change
     149        $(document).on('change', 'input.qty, input[name="quantity"]', function() {
     150            validateQuantity($(this));
     151        });
     152
     153        // Validate quantity before add to cart
     154        $(document).on('click', '.single_add_to_cart_button', function(e) {
     155            if (!validateBeforeAddToCart()) {
     156                e.preventDefault();
     157                return false;
     158            }
     159        });
     160    }
     161
     162    /**
     163     * Validate quantity against selected location stock
     164     */
     165    function validateQuantity($qtyInput) {
     166        if (!selectedLocationId) {
     167            return true; // Will be caught by add to cart validation
     168        }
     169
     170        var quantity = parseInt($qtyInput.val());
     171        var productId = $('input[name="add-to-cart"]').val() || $('input[name="product_id"]').val();
     172        var variationId = $('input[name="variation_id"]').val() || 0;
     173       
     174        if (!productId || !quantity) {
     175            return true;
     176        }
     177
     178        $.ajax({
     179            url: multiloca_lite.ajax_url,
     180            type: 'POST',
     181            data: {
     182                action: 'validate_location_stock',
     183                product_id: productId,
     184                variation_id: variationId,
     185                location_id: selectedLocationId,
     186                quantity: quantity,
     187                nonce: multiloca_lite.nonce
     188            },
     189            success: function(response) {
     190                if (!response.success) {
     191                    $qtyInput.val(response.data.available_stock);
     192                    showMessage(response.data.message, 'error');
     193                }
     194            }
     195        });
     196    }
     197
     198    /**
     199     * Update quantity field max value
     200     */
     201    function updateQuantityMax() {
     202        if (!selectedLocationId) return;
     203
     204        var productId = $('input[name="add-to-cart"]').val() || $('input[name="product_id"]').val();
     205        var variationId = $('input[name="variation_id"]').val() || 0;
     206        if (!productId) return;
     207
     208        $.ajax({
     209            url: multiloca_lite.ajax_url,
     210            type: 'POST',
     211            data: {
     212                action: 'validate_location_stock',
     213                product_id: productId,
     214                variation_id: variationId,
     215                location_id: selectedLocationId,
     216                quantity: 1,
     217                nonce: multiloca_lite.nonce
     218            },
     219            success: function(response) {
     220                if (response.success && response.data.available_stock) {
     221                    $('input.qty, input[name="quantity"]').attr('max', response.data.available_stock);
     222                }
     223            }
     224        });
     225    }
     226
     227    /**
     228     * Validate before add to cart
     229     */
     230    function validateBeforeAddToCart() {
     231        if (!selectedLocationId) {
     232            showMessage(multiloca_lite.messages.select_location, 'error');
     233            return false;
     234        }
     235        return true;
     236    }
     237
     238    /**
     239     * Show message to user
     240     */
     241    function showMessage(message, type) {
     242        // Remove existing messages
     243        $('.multiloca-message').remove();
     244       
     245        var messageClass = type === 'error' ? 'woocommerce-error' : 'woocommerce-message';
     246        var messageHtml = '<div class="multiloca-message ' + messageClass + '">' + message + '</div>';
     247       
     248        // Insert message before add to cart form
     249        if ($('.cart').length) {
     250            $('.cart').before(messageHtml);
     251        } else {
     252            $('.multiloca-lite-inventory').after(messageHtml);
     253        }
     254       
     255        // Auto remove after 5 seconds
     256        setTimeout(function() {
     257            $('.multiloca-message').fadeOut();
     258        }, 5000);
     259    }
    32260
    33261    function updateStockForVariationProduct(variationId) {
     
    129357    $('form.variations_form').on('woocommerce_variation_has_changed', function() {
    130358        var selectedVariationId = $('input[name="variation_id"]').val();
     359       
     360        // Reset selected location when variation changes
     361        selectedLocationId = null;
     362        selectedLocationName = null;
     363        $('.multiloca-location-selected').removeClass('multiloca-location-selected');
     364        $('.multiloca-selected-location-info').remove();
     365       
    131366        updateStockForVariationProduct(selectedVariationId);
    132367    });
  • multiloca-lite-multi-location-inventory/trunk/readme.txt

    r3336945 r3374381  
    44Requires at least: 5.0
    55Tested up to: 6.8
    6 Stable tag: 1.0.2
     6Stable tag: 1.1.0
    77Requires PHP: 7.0
    88License: GPLv2 or later
     
    2727* **Shortcodes**: Display location information anywhere on your site.
    2828
    29 = Premium Features =
     29= Pro Features =
    3030
    3131Looking for more advanced features? Check out our Pro version which includes:
     
    3838* Auto stock allocation
    3939* Location manager roles and permissions
     40* And much more!
     41
     42= Premium Features =
     43
     44Looking for Enterprise level features? Check out our Premium version which includes:
     45
     46* All features in Pro version
     47* Rule based automatic & advanced location fullfillment for orders
     48* Create & Manage vendors and Purchase orders.
     49* Initiaze stock transfers between locations
    4050* And much more!
    4151
     
    8292= 1.0.0 =
    8393This is the initial release of Multiloca Lite.
     94
     95= 1.0.2 =
     96Added new display views for location stock display on frontend
     97
     98= 1.1.0 =
     99Major Update - Added support for order fulfilment with user selected location.
     100
     101
Note: See TracChangeset for help on using the changeset viewer.