Changeset 3374381
- Timestamp:
- 10/07/2025 12:29:20 PM (6 months ago)
- Location:
- multiloca-lite-multi-location-inventory/trunk
- Files:
-
- 5 added
- 5 deleted
- 12 edited
-
admin/css/multiloca-lite-admin.css (modified) (1 diff)
-
admin/js/multiloca-lite-product-edit.js (added)
-
admin/partials/multiloca-lite-custom-inventory-fields.php (modified) (5 diffs)
-
admin/partials/multiloca-lite-settings.php (modified) (2 diffs)
-
includes/class-multiloca-lite-cart-location.php (added)
-
includes/class-multiloca-lite.php (deleted)
-
includes/helper (added)
-
includes/helper/multiloca-lite-inventory-helper.php (added)
-
multiloca-lite-multi-location-inventory.php (added)
-
multiloca-lite-multi-locations-inventory-management.php (deleted)
-
public/class-multiloca-lite-public.php (modified) (1 diff)
-
public/controller/shop/views/multiloca-card-view.php (modified) (1 diff)
-
public/controller/shop/views/multiloca-drawer-view.php (deleted)
-
public/controller/shop/views/multiloca-expanded-view.php (modified) (1 diff)
-
public/controller/shop/views/multiloca-list-view.php (modified) (1 diff)
-
public/controller/shop/views/multiloca-popup-view.php (deleted)
-
public/controller/shop/views/multiloca-select-view.php (deleted)
-
public/controller/shop/views/multiloca-simple-text-view.php (modified) (1 diff)
-
public/controller/shop/views/multiloca-table-view.php (modified) (1 diff)
-
public/css/multiloca-lite-public.css (modified) (1 diff)
-
public/js/multiloca-lite-public.js (modified) (3 diffs)
-
readme.txt (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
multiloca-lite-multi-location-inventory/trunk/admin/css/multiloca-lite-admin.css
r3336945 r3374381 143 143 .multiloca-preview-container h3 { 144 144 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; 145 171 } 146 172 -
multiloca-lite-multi-location-inventory/trunk/admin/partials/multiloca-lite-custom-inventory-fields.php
r3336945 r3374381 110 110 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 111 111 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) . '">'; 113 113 echo '<div class="multiloca-lite-location-header">'; 114 114 echo '<h4><span class="multiloca-toggle-icon">+</span> ' . esc_html($location->name) . '</h4>'; … … 222 222 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 223 223 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) . '">'; 225 225 echo '<td>' . esc_html($location->name) . '</td>'; 226 226 echo '<td>'; … … 308 308 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 309 309 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) . '">'; 311 311 echo '<span class="location-name">' . esc_html($location->name) . '</span>: '; 312 312 echo wp_kses_post($stock_text); … … 389 389 '<span class="stock-label out-of-stock">' . esc_html($outofstock_text) . '</span>'; 390 390 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) . '">'; 392 392 echo '<div class="location-header">'; 393 393 echo '<span class="location-name">' . esc_html($location->name) . '</span>'; … … 476 476 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 477 477 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) . '">'; 479 479 echo '<div class="card-header">'; 480 480 echo '<div class="location-name">'; -
multiloca-lite-multi-location-inventory/trunk/admin/partials/multiloca-lite-settings.php
r3336945 r3374381 24 24 25 25 <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> 27 30 28 31 <div class="ml-panels"> … … 45 48 </form> 46 49 </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"> 48 109 <div class="multiloca-container"> 49 110 <div class="section-title">Getting Started</div> -
multiloca-lite-multi-location-inventory/trunk/public/class-multiloca-lite-public.php
r3336945 r3374381 57 57 ); 58 58 59 // Localize script with AJAX URL 59 // Localize script with AJAX URL and messages 60 60 wp_localize_script('multiloca-lite-public', 'multiloca_lite', array( 61 61 '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 ) 63 68 )); 64 69 } -
multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-card-view.php
r3336945 r3374381 80 80 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 81 81 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) . '">'; 83 83 echo '<div class="card-header">'; 84 84 echo '<div class="location-name">'; -
multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-expanded-view.php
r3336945 r3374381 80 80 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 81 81 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) . '">'; 83 83 echo '<div class="multiloca-lite-location-header">'; 84 84 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 80 80 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 81 81 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) . '">'; 83 83 echo '<span class="location-name">' . esc_html($location->name) . '</span>: '; 84 84 echo wp_kses_post($stock_text); -
multiloca-lite-multi-location-inventory/trunk/public/controller/shop/views/multiloca-simple-text-view.php
r3336945 r3374381 80 80 '<span class="stock-label out-of-stock">' . esc_html($outofstock_text) . '</span>'; 81 81 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) . '">'; 83 83 echo '<div class="location-header">'; 84 84 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 86 86 '<span class="stock out-of-stock">' . esc_html($outofstock_text) . '</span>'; 87 87 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) . '">'; 89 89 echo '<td>' . esc_html($location->name) . '</td>'; 90 90 -
multiloca-lite-multi-location-inventory/trunk/public/css/multiloca-lite-public.css
r3336945 r3374381 193 193 194 194 .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; 202 289 } 203 290 -
multiloca-lite-multi-location-inventory/trunk/public/js/multiloca-lite-public.js
r3336945 r3374381 6 6 'use strict'; 7 7 8 // Global variables for location selection 9 var selectedLocationId = null; 10 var selectedLocationName = null; 11 8 12 // Function to initialize on page load 9 13 $(document).ready(function() { 14 // Initialize location selection functionality 15 initializeLocationSelection(); 16 17 // Initialize quantity validation 18 initializeQuantityValidation(); 19 10 20 // Initialize expanded view functionality with event delegation 11 21 $(document).on('click', '.multiloca-lite-location-header', function(e) { … … 30 40 }); 31 41 }); 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 } 32 260 33 261 function updateStockForVariationProduct(variationId) { … … 129 357 $('form.variations_form').on('woocommerce_variation_has_changed', function() { 130 358 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 131 366 updateStockForVariationProduct(selectedVariationId); 132 367 }); -
multiloca-lite-multi-location-inventory/trunk/readme.txt
r3336945 r3374381 4 4 Requires at least: 5.0 5 5 Tested up to: 6.8 6 Stable tag: 1. 0.26 Stable tag: 1.1.0 7 7 Requires PHP: 7.0 8 8 License: GPLv2 or later … … 27 27 * **Shortcodes**: Display location information anywhere on your site. 28 28 29 = Pr emiumFeatures =29 = Pro Features = 30 30 31 31 Looking for more advanced features? Check out our Pro version which includes: … … 38 38 * Auto stock allocation 39 39 * Location manager roles and permissions 40 * And much more! 41 42 = Premium Features = 43 44 Looking 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 40 50 * And much more! 41 51 … … 82 92 = 1.0.0 = 83 93 This is the initial release of Multiloca Lite. 94 95 = 1.0.2 = 96 Added new display views for location stock display on frontend 97 98 = 1.1.0 = 99 Major Update - Added support for order fulfilment with user selected location. 100 101
Note: See TracChangeset
for help on using the changeset viewer.