mirror of
https://github.com/inventree/InvenTree
synced 2024-08-30 18:33:04 +00:00
Calendar view for build orders
This commit is contained in:
parent
76c86e7b2f
commit
47b0f40e97
@ -90,6 +90,13 @@ class BuildList(generics.ListCreateAPIView):
|
|||||||
if part is not None:
|
if part is not None:
|
||||||
queryset = queryset.filter(part=part)
|
queryset = queryset.filter(part=part)
|
||||||
|
|
||||||
|
# Filter by 'date range'
|
||||||
|
min_date = params.get('min_date', None)
|
||||||
|
max_date = params.get('max_date', None)
|
||||||
|
|
||||||
|
if min_date is not None and max_date is not None:
|
||||||
|
queryset = Build.filterByDate(queryset, min_date, max_date)
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
def get_serializer(self, *args, **kwargs):
|
def get_serializer(self, *args, **kwargs):
|
||||||
|
@ -61,6 +61,37 @@ class Build(MPTTModel):
|
|||||||
verbose_name = _("Build Order")
|
verbose_name = _("Build Order")
|
||||||
verbose_name_plural = _("Build Orders")
|
verbose_name_plural = _("Build Orders")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def filterByDate(queryset, min_date, max_date):
|
||||||
|
"""
|
||||||
|
Filter by 'minimum and maximum date range'
|
||||||
|
|
||||||
|
- Specified as min_date, max_date
|
||||||
|
- Both must be specified for filter to be applied
|
||||||
|
"""
|
||||||
|
|
||||||
|
date_fmt = '%Y-%m-%d' # ISO format date string
|
||||||
|
|
||||||
|
# Ensure that both dates are valid
|
||||||
|
try:
|
||||||
|
min_date = datetime.strptime(str(min_date), date_fmt).date()
|
||||||
|
max_date = datetime.strptime(str(max_date), date_fmt).date()
|
||||||
|
except (ValueError, TypeError):
|
||||||
|
# Date processing error, return queryset unchanged
|
||||||
|
return queryset
|
||||||
|
|
||||||
|
# Order was completed within the specified range
|
||||||
|
completed = Q(status=BuildStatus.COMPLETE) & Q(completion_date__gte=min_date) & Q(completion_date__lte=max_date)
|
||||||
|
|
||||||
|
# Order target date falls witin specified range
|
||||||
|
pending = Q(status__in=BuildStatus.ACTIVE_CODES) & ~Q(target_date=None) & Q(target_date__gte=min_date) & Q(target_date__lte=max_date)
|
||||||
|
|
||||||
|
# TODO - Construct a queryset for "overdue" orders
|
||||||
|
|
||||||
|
queryset = queryset.filter(completed | pending)
|
||||||
|
|
||||||
|
return queryset
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
||||||
prefix = getSetting("BUILDORDER_REFERENCE_PREFIX")
|
prefix = getSetting("BUILDORDER_REFERENCE_PREFIX")
|
||||||
|
@ -88,11 +88,20 @@ src="{% static 'img/blank_image.png' %}"
|
|||||||
<td>{% trans "Status" %}</td>
|
<td>{% trans "Status" %}</td>
|
||||||
<td>
|
<td>
|
||||||
{% build_status_label build.status %}
|
{% build_status_label build.status %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% if build.target_date %}
|
||||||
|
<tr>
|
||||||
|
<td><span class='fas fa-calendar-alt'></span></td>
|
||||||
|
<td>{% trans "Target Date" %}</td>
|
||||||
|
<td>
|
||||||
|
{{ build.target_date }}
|
||||||
{% if build.is_overdue %}
|
{% if build.is_overdue %}
|
||||||
<span title='{% trans "This build was due on" %} {{ build.target_date }}' class='label label-red'>{% trans "Overdue" %}</span>
|
<span title='{% trans "This build was due on" %} {{ build.target_date }}' class='label label-red'>{% trans "Overdue" %}</span>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
{% endif %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><span class='fas fa-spinner'></span></td>
|
<td><span class='fas fa-spinner'></span></td>
|
||||||
<td>{% trans "Progress" %}</td>
|
<td>{% trans "Progress" %}</td>
|
||||||
|
@ -1,4 +1,6 @@
|
|||||||
{% extends "base.html" %}
|
{% extends "base.html" %}
|
||||||
|
|
||||||
|
{% load inventree_extras %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
|
||||||
@ -8,7 +10,6 @@ InvenTree | {% trans "Build Orders" %}
|
|||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
|
|
||||||
|
|
||||||
<div class='row'>
|
<div class='row'>
|
||||||
<div class='col-sm-6'>
|
<div class='col-sm-6'>
|
||||||
<h3>{% trans "Build Orders" %}</h3>
|
<h3>{% trans "Build Orders" %}</h3>
|
||||||
@ -21,8 +22,17 @@ InvenTree | {% trans "Build Orders" %}
|
|||||||
|
|
||||||
<div id='button-toolbar'>
|
<div id='button-toolbar'>
|
||||||
<div class='button-toolbar container-fluid' style='float: right;'>
|
<div class='button-toolbar container-fluid' style='float: right;'>
|
||||||
|
{% if roles.build.add %}
|
||||||
<button type='button' class="btn btn-success" id='new-build'>
|
<button type='button' class="btn btn-success" id='new-build'>
|
||||||
<span class='fas fa-tools'></span> {% trans "New Build Order" %}</button>
|
<span class='fas fa-tools'></span> {% trans "New Build Order" %}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
<button class='btn btn-default' type='button' id='view-calendar' title='{% trans "Display calendar view" %}'>
|
||||||
|
<span class='fas fa-calendar-alt'></span>
|
||||||
|
</button>
|
||||||
|
<button class='btn btn-default' type='button' id='view-list' title='{% trans "Display list view" %}'>
|
||||||
|
<span class='fas fa-th-list'></span>
|
||||||
|
</button>
|
||||||
<div class='filter-list' id='filter-list-build'>
|
<div class='filter-list' id='filter-list-build'>
|
||||||
<!-- An empty div in which the filter list will be constructed -->
|
<!-- An empty div in which the filter list will be constructed -->
|
||||||
</div>
|
</div>
|
||||||
@ -33,11 +43,120 @@ InvenTree | {% trans "Build Orders" %}
|
|||||||
<table class='table table-striped table-condensed' id='build-table' data-toolbar='#button-toolbar'>
|
<table class='table table-striped table-condensed' id='build-table' data-toolbar='#button-toolbar'>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
<div id='build-order-calendar'></div>
|
||||||
|
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block js_load %}
|
||||||
|
{{ block.super }}
|
||||||
|
|
||||||
|
<script type='text/javascript'>
|
||||||
|
function loadOrderEvents(calendar) {
|
||||||
|
|
||||||
|
var start = startDate(calendar);
|
||||||
|
var end = endDate(calendar);
|
||||||
|
|
||||||
|
clearEvents(calendar);
|
||||||
|
|
||||||
|
// Request build orders from the server within specified date range
|
||||||
|
inventreeGet(
|
||||||
|
'{% url "api-build-list" %}',
|
||||||
|
{
|
||||||
|
min_date: start,
|
||||||
|
max_date: end,
|
||||||
|
part_detail: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
success: function(response) {
|
||||||
|
var prefix = '{% settings_value "BUILDORDER_REFERENCE_PREFIX" %}';
|
||||||
|
|
||||||
|
for (var idx = 0; idx < response.length; idx++) {
|
||||||
|
|
||||||
|
var order = response[idx];
|
||||||
|
|
||||||
|
var date = order.creation_date;
|
||||||
|
|
||||||
|
if (order.completion_date) {
|
||||||
|
date = order.completion_date;
|
||||||
|
} else if (order.target_date) {
|
||||||
|
date = order.target_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
var title = `${prefix}${order.reference}`; //- ${order.quantity} x ${order.part_detail.name}`;
|
||||||
|
|
||||||
|
var color = '#4c68f5';
|
||||||
|
|
||||||
|
if (order.completed) {
|
||||||
|
color = '#25c234';
|
||||||
|
} else if (order.overdue) {
|
||||||
|
color = '#c22525';
|
||||||
|
}
|
||||||
|
|
||||||
|
var event = {
|
||||||
|
title: title,
|
||||||
|
start: date,
|
||||||
|
end: date,
|
||||||
|
url: `/build/${order.pk}/`,
|
||||||
|
backgroundColor: color,
|
||||||
|
};
|
||||||
|
|
||||||
|
calendar.addEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
var calendar = null;
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
var el = document.getElementById('build-order-calendar');
|
||||||
|
|
||||||
|
calendar = new FullCalendar.Calendar(el, {
|
||||||
|
initialView: 'dayGridMonth',
|
||||||
|
nowIndicator: true,
|
||||||
|
aspectRatio: 2.5,
|
||||||
|
datesSet: function() {
|
||||||
|
loadOrderEvents(calendar);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
calendar.render();
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block js_ready %}
|
{% block js_ready %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
|
|
||||||
|
$('#build-order-calendar').hide();
|
||||||
|
$('#view-list').hide();
|
||||||
|
|
||||||
|
$('#view-calendar').click(function() {
|
||||||
|
// Hide the list view, show the calendar view
|
||||||
|
$("#build-table").hide();
|
||||||
|
$("#view-calendar").hide();
|
||||||
|
$(".fixed-table-pagination").hide();
|
||||||
|
$(".columns-right").hide();
|
||||||
|
$(".search").hide();
|
||||||
|
|
||||||
|
$("#build-order-calendar").show();
|
||||||
|
$("#view-list").show();
|
||||||
|
});
|
||||||
|
|
||||||
|
$("#view-list").click(function() {
|
||||||
|
// Hide the calendar view, show the list view
|
||||||
|
$("#build-order-calendar").hide();
|
||||||
|
$("#view-list").hide();
|
||||||
|
|
||||||
|
$(".fixed-table-pagination").show();
|
||||||
|
$(".columns-right").show();
|
||||||
|
$(".search").show();
|
||||||
|
$("#build-table").show();
|
||||||
|
$("#view-calendar").show();
|
||||||
|
});
|
||||||
|
|
||||||
$("#collapse-item-active").collapse().show();
|
$("#collapse-item-active").collapse().show();
|
||||||
|
|
||||||
$("#new-build").click(function() {
|
$("#new-build").click(function() {
|
||||||
|
@ -372,9 +372,7 @@ class SalesOrder(Order):
|
|||||||
|
|
||||||
# TODO: Construct a queryset for "overdue" orders within the range
|
# TODO: Construct a queryset for "overdue" orders within the range
|
||||||
|
|
||||||
flt = completed | pending
|
queryset = queryset.filter(completed | pending)
|
||||||
|
|
||||||
queryset = queryset.filter(flt)
|
|
||||||
|
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
|
@ -74,7 +74,15 @@ InvenTree | {% trans "Purchase Orders" %}
|
|||||||
|
|
||||||
var title = `${prefix}${order.reference} - ${order.supplier_detail.name}`;
|
var title = `${prefix}${order.reference} - ${order.supplier_detail.name}`;
|
||||||
|
|
||||||
var color = '#25c235';
|
var color = '#4c68f5';
|
||||||
|
|
||||||
|
if (order.complete_date) {
|
||||||
|
color = '#25c235';
|
||||||
|
} else if (order.overdue) {
|
||||||
|
color = '#c22525';
|
||||||
|
} else {
|
||||||
|
color = '#4c68f5';
|
||||||
|
}
|
||||||
|
|
||||||
var event = {
|
var event = {
|
||||||
title: title,
|
title: title,
|
||||||
@ -106,7 +114,7 @@ InvenTree | {% trans "Purchase Orders" %}
|
|||||||
});
|
});
|
||||||
|
|
||||||
calendar.render();
|
calendar.render();
|
||||||
})
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user