mirror of
				https://github.com/inventree/InvenTree.git
				synced 2025-10-31 05:05:42 +00:00 
			
		
		
		
	Merge pull request #2695 from SchrodingersGat/scheduling
[WIP] Scheduling
This commit is contained in:
		| @@ -18,6 +18,7 @@ | ||||
|             {% include "InvenTree/settings/setting.html" with key="DATE_DISPLAY_FORMAT" icon="fa-calendar-alt" user_setting=True %} | ||||
|             {% include "InvenTree/settings/setting.html" with key="FORMS_CLOSE_USING_ESCAPE" icon="fa-window-close" user_setting=True %} | ||||
|             {% include "InvenTree/settings/setting.html" with key="PART_SHOW_QUANTITY_IN_FORMS" icon="fa-hashtag" user_setting=True %} | ||||
|             {% include "InvenTree/settings/setting.html" with key="DISPLAY_SCHEDULE_TAB" icon="fa-calendar-alt" user_setting=True %} | ||||
|         </tbody> | ||||
|     </table> | ||||
| </div> | ||||
|   | ||||
| @@ -153,8 +153,10 @@ | ||||
| <script type="text/javascript" src="{% static 'fullcalendar/main.js' %}"></script> | ||||
| <script type="text/javascript" src="{% static 'fullcalendar/locales-all.js' %}"></script> | ||||
| <script type="text/javascript" src="{% static 'select2/js/select2.full.js' %}"></script> | ||||
| <script type='text/javascript' src="{% static 'script/chart.js' %}"></script> | ||||
| <script type='text/javascript' src="{% static 'script/moment.js' %}"></script> | ||||
| <script type='text/javascript' src="{% static 'script/chart.min.js' %}"></script> | ||||
| <script type='text/javascript' src="{% static 'script/chartjs-adapter-moment.js' %}"></script> | ||||
|      | ||||
| <script type='text/javascript' src="{% static 'script/clipboard.min.js' %}"></script> | ||||
| <script type='text/javascript' src="{% static 'script/randomColor.min.js' %}"></script> | ||||
|  | ||||
|   | ||||
| @@ -33,6 +33,7 @@ | ||||
|     loadPartPurchaseOrderTable, | ||||
|     loadPartTable, | ||||
|     loadPartTestTemplateTable, | ||||
|     loadPartSchedulingChart, | ||||
|     loadPartVariantTable, | ||||
|     loadRelatedPartsTable, | ||||
|     loadSellPricingChart, | ||||
| @@ -1981,6 +1982,123 @@ function initPriceBreakSet(table, options) { | ||||
| } | ||||
|  | ||||
|  | ||||
| function loadPartSchedulingChart(canvas_id, part_id) { | ||||
|  | ||||
|     var part_info = null; | ||||
|  | ||||
|     // First, grab updated data for the particular part | ||||
|     inventreeGet(`/api/part/${part_id}/`, {}, { | ||||
|         async: false, | ||||
|         success: function(response) { | ||||
|             part_info = response; | ||||
|         } | ||||
|     }); | ||||
|  | ||||
|     var today = moment(); | ||||
|  | ||||
|     // Create an initial entry, using the available quantity | ||||
|     var stock_schedule = [ | ||||
|         { | ||||
|             date: today, | ||||
|             delta: 0, | ||||
|             label: '{% trans "Current Stock" %}', | ||||
|         } | ||||
|     ]; | ||||
|  | ||||
|     /* Request scheduling information for the part. | ||||
|      * Note that this information has already been 'curated' by the server, | ||||
|      * and arranged in increasing chronological order | ||||
|      */ | ||||
|     inventreeGet( | ||||
|         `/api/part/${part_id}/scheduling/`, | ||||
|         {}, | ||||
|         { | ||||
|             async: false, | ||||
|             success: function(response) { | ||||
|                 response.forEach(function(entry) { | ||||
|                     stock_schedule.push({ | ||||
|                         date: moment(entry.date), | ||||
|                         delta: entry.quantity, | ||||
|                         title: entry.title, | ||||
|                         label: entry.label, | ||||
|                         url: entry.url, | ||||
|                     }); | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     ); | ||||
|  | ||||
|     // Iterate through future "events" to calculate expected quantity | ||||
|  | ||||
|     var quantity = part_info.in_stock; | ||||
|  | ||||
|     for (var idx = 0; idx < stock_schedule.length; idx++) { | ||||
|  | ||||
|         quantity += stock_schedule[idx].delta; | ||||
|  | ||||
|         stock_schedule[idx].x = stock_schedule[idx].date.format('YYYY-MM-DD'); | ||||
|         stock_schedule[idx].y = quantity; | ||||
|     } | ||||
|  | ||||
|     var context = document.getElementById(canvas_id); | ||||
|  | ||||
|     const data = { | ||||
|         datasets: [{ | ||||
|             label: '{% trans "Scheduled Stock Quantities" %}', | ||||
|             data: stock_schedule, | ||||
|             backgroundColor: 'rgb(220, 160, 80)', | ||||
|             borderWidth: 2, | ||||
|             borderColor: 'rgb(90, 130, 150)' | ||||
|         }], | ||||
|     }; | ||||
|  | ||||
|     return new Chart(context, { | ||||
|         type: 'scatter', | ||||
|         data: data, | ||||
|         options: { | ||||
|             showLine: true, | ||||
|             stepped: true, | ||||
|             scales: { | ||||
|                 x: { | ||||
|                     type: 'time', | ||||
|                     min: today.format(), | ||||
|                     position: 'bottom', | ||||
|                     time: { | ||||
|                         unit: 'day', | ||||
|                     }, | ||||
|                 }, | ||||
|                 y: { | ||||
|                     beginAtZero: true, | ||||
|                 } | ||||
|             }, | ||||
|             plugins: { | ||||
|                 tooltip: { | ||||
|                     callbacks: { | ||||
|                         label: function(item) { | ||||
|                             return item.raw.label; | ||||
|                         }, | ||||
|                         beforeLabel: function(item) { | ||||
|                             return item.raw.title; | ||||
|                         }, | ||||
|                         afterLabel: function(item) { | ||||
|                             var delta = item.raw.delta; | ||||
|  | ||||
|                             if (delta == 0) { | ||||
|                                 delta = ''; | ||||
|                             } else { | ||||
|                                 delta = ` (${item.raw.delta > 0 ? '+' : ''}${item.raw.delta})`; | ||||
|                             } | ||||
|  | ||||
|                             return `{% trans "Quantity" %}: ${item.raw.y}${delta}`; | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             }, | ||||
|         } | ||||
|     }); | ||||
| } | ||||
|  | ||||
|  | ||||
| function loadStockPricingChart(context, data) { | ||||
|     return new Chart(context, { | ||||
|         type: 'bar', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user