Merge remote-tracking branch 'inventree/master'

This commit is contained in:
Oliver Walters 2021-01-08 08:38:18 +11:00
commit f21a0704a8
136 changed files with 23299 additions and 2083 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var af = {
code: 'af',
week: {
dow: 1, // Maandag is die eerste dag van die week.
doy: 4, // Die week wat die 4de Januarie bevat is die eerste week van die jaar.
},
buttonText: {
prev: 'Vorige',
next: 'Volgende',
today: 'Vandag',
year: 'Jaar',
month: 'Maand',
week: 'Week',
day: 'Dag',
list: 'Agenda',
},
allDayText: 'Heeldag',
moreLinkText: 'Addisionele',
noEventsText: 'Daar is geen gebeurtenisse nie',
};
return af;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var arDz = {
code: 'ar-dz',
week: {
dow: 0, // Sunday is the first day of the week.
doy: 4, // The week that contains Jan 1st is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'السابق',
next: 'التالي',
today: 'اليوم',
month: 'شهر',
week: 'أسبوع',
day: 'يوم',
list: 'أجندة',
},
weekText: 'أسبوع',
allDayText: 'اليوم كله',
moreLinkText: 'أخرى',
noEventsText: 'أي أحداث لعرض',
};
return arDz;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var arKw = {
code: 'ar-kw',
week: {
dow: 0, // Sunday is the first day of the week.
doy: 12, // The week that contains Jan 1st is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'السابق',
next: 'التالي',
today: 'اليوم',
month: 'شهر',
week: 'أسبوع',
day: 'يوم',
list: 'أجندة',
},
weekText: 'أسبوع',
allDayText: 'اليوم كله',
moreLinkText: 'أخرى',
noEventsText: 'أي أحداث لعرض',
};
return arKw;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var arLy = {
code: 'ar-ly',
week: {
dow: 6, // Saturday is the first day of the week.
doy: 12, // The week that contains Jan 1st is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'السابق',
next: 'التالي',
today: 'اليوم',
month: 'شهر',
week: 'أسبوع',
day: 'يوم',
list: 'أجندة',
},
weekText: 'أسبوع',
allDayText: 'اليوم كله',
moreLinkText: 'أخرى',
noEventsText: 'أي أحداث لعرض',
};
return arLy;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var arMa = {
code: 'ar-ma',
week: {
dow: 6, // Saturday is the first day of the week.
doy: 12, // The week that contains Jan 1st is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'السابق',
next: 'التالي',
today: 'اليوم',
month: 'شهر',
week: 'أسبوع',
day: 'يوم',
list: 'أجندة',
},
weekText: 'أسبوع',
allDayText: 'اليوم كله',
moreLinkText: 'أخرى',
noEventsText: 'أي أحداث لعرض',
};
return arMa;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var arSa = {
code: 'ar-sa',
week: {
dow: 0, // Sunday is the first day of the week.
doy: 6, // The week that contains Jan 1st is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'السابق',
next: 'التالي',
today: 'اليوم',
month: 'شهر',
week: 'أسبوع',
day: 'يوم',
list: 'أجندة',
},
weekText: 'أسبوع',
allDayText: 'اليوم كله',
moreLinkText: 'أخرى',
noEventsText: 'أي أحداث لعرض',
};
return arSa;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var arTn = {
code: 'ar-tn',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'السابق',
next: 'التالي',
today: 'اليوم',
month: 'شهر',
week: 'أسبوع',
day: 'يوم',
list: 'أجندة',
},
weekText: 'أسبوع',
allDayText: 'اليوم كله',
moreLinkText: 'أخرى',
noEventsText: 'أي أحداث لعرض',
};
return arTn;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ar = {
code: 'ar',
week: {
dow: 6, // Saturday is the first day of the week.
doy: 12, // The week that contains Jan 1st is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'السابق',
next: 'التالي',
today: 'اليوم',
month: 'شهر',
week: 'أسبوع',
day: 'يوم',
list: 'أجندة',
},
weekText: 'أسبوع',
allDayText: 'اليوم كله',
moreLinkText: 'أخرى',
noEventsText: 'أي أحداث لعرض',
};
return ar;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var az = {
code: 'az',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Əvvəl',
next: 'Sonra',
today: 'Bu Gün',
month: 'Ay',
week: 'Həftə',
day: 'Gün',
list: 'Gündəm',
},
weekText: 'Həftə',
allDayText: 'Bütün Gün',
moreLinkText: function(n) {
return '+ daha çox ' + n
},
noEventsText: 'Göstərmək üçün hadisə yoxdur',
};
return az;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var bg = {
code: 'bg',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'назад',
next: 'напред',
today: 'днес',
month: 'Месец',
week: 'Седмица',
day: 'Ден',
list: 'График',
},
allDayText: 'Цял ден',
moreLinkText: function(n) {
return '+още ' + n
},
noEventsText: 'Няма събития за показване',
};
return bg;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var bs = {
code: 'bs',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Prošli',
next: 'Sljedeći',
today: 'Danas',
month: 'Mjesec',
week: 'Sedmica',
day: 'Dan',
list: 'Raspored',
},
weekText: 'Sed',
allDayText: 'Cijeli dan',
moreLinkText: function(n) {
return '+ još ' + n
},
noEventsText: 'Nema događaja za prikazivanje',
};
return bs;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ca = {
code: 'ca',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Anterior',
next: 'Següent',
today: 'Avui',
month: 'Mes',
week: 'Setmana',
day: 'Dia',
list: 'Agenda',
},
weekText: 'Set',
allDayText: 'Tot el dia',
moreLinkText: 'més',
noEventsText: 'No hi ha esdeveniments per mostrar',
};
return ca;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var cs = {
code: 'cs',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Dříve',
next: 'Později',
today: 'Nyní',
month: 'Měsíc',
week: 'Týden',
day: 'Den',
list: 'Agenda',
},
weekText: 'Týd',
allDayText: 'Celý den',
moreLinkText: function(n) {
return '+další: ' + n
},
noEventsText: 'Žádné akce k zobrazení',
};
return cs;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var cy = {
code: 'cy',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Blaenorol',
next: 'Nesaf',
today: 'Heddiw',
year: 'Blwyddyn',
month: 'Mis',
week: 'Wythnos',
day: 'Dydd',
list: 'Rhestr',
},
weekText: 'Wythnos',
allDayText: 'Trwy\'r dydd',
moreLinkText: 'Mwy',
noEventsText: 'Dim digwyddiadau',
};
return cy;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var da = {
code: 'da',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Forrige',
next: 'Næste',
today: 'I dag',
month: 'Måned',
week: 'Uge',
day: 'Dag',
list: 'Agenda',
},
weekText: 'Uge',
allDayText: 'Hele dagen',
moreLinkText: 'flere',
noEventsText: 'Ingen arrangementer at vise',
};
return da;
}());

View File

@ -0,0 +1,30 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var deAt = {
code: 'de-at',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Zurück',
next: 'Vor',
today: 'Heute',
year: 'Jahr',
month: 'Monat',
week: 'Woche',
day: 'Tag',
list: 'Terminübersicht',
},
weekText: 'KW',
allDayText: 'Ganztägig',
moreLinkText: function(n) {
return '+ weitere ' + n
},
noEventsText: 'Keine Ereignisse anzuzeigen',
};
return deAt;
}());

View File

@ -0,0 +1,30 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var de = {
code: 'de',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Zurück',
next: 'Vor',
today: 'Heute',
year: 'Jahr',
month: 'Monat',
week: 'Woche',
day: 'Tag',
list: 'Terminübersicht',
},
weekText: 'KW',
allDayText: 'Ganztägig',
moreLinkText: function(n) {
return '+ weitere ' + n
},
noEventsText: 'Keine Ereignisse anzuzeigen',
};
return de;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var el = {
code: 'el',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4st is the first week of the year.
},
buttonText: {
prev: 'Προηγούμενος',
next: 'Επόμενος',
today: 'Σήμερα',
month: 'Μήνας',
week: 'Εβδομάδα',
day: 'Ημέρα',
list: 'Ατζέντα',
},
weekText: 'Εβδ',
allDayText: 'Ολοήμερο',
moreLinkText: 'περισσότερα',
noEventsText: 'Δεν υπάρχουν γεγονότα προς εμφάνιση',
};
return el;
}());

View File

@ -0,0 +1,14 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var enAu = {
code: 'en-au',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
};
return enAu;
}());

View File

@ -0,0 +1,14 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var enGb = {
code: 'en-gb',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
};
return enGb;
}());

View File

@ -0,0 +1,14 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var enNz = {
code: 'en-nz',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
};
return enNz;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var eo = {
code: 'eo',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Antaŭa',
next: 'Sekva',
today: 'Hodiaŭ',
month: 'Monato',
week: 'Semajno',
day: 'Tago',
list: 'Tagordo',
},
weekText: 'Sm',
allDayText: 'Tuta tago',
moreLinkText: 'pli',
noEventsText: 'Neniuj eventoj por montri',
};
return eo;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var esUs = {
code: 'es',
week: {
dow: 0, // Sunday is the first day of the week.
doy: 6, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Ant',
next: 'Sig',
today: 'Hoy',
month: 'Mes',
week: 'Semana',
day: 'Día',
list: 'Agenda',
},
weekText: 'Sm',
allDayText: 'Todo el día',
moreLinkText: 'más',
noEventsText: 'No hay eventos para mostrar',
};
return esUs;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var es = {
code: 'es',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Ant',
next: 'Sig',
today: 'Hoy',
month: 'Mes',
week: 'Semana',
day: 'Día',
list: 'Agenda',
},
weekText: 'Sm',
allDayText: 'Todo el día',
moreLinkText: 'más',
noEventsText: 'No hay eventos para mostrar',
};
return es;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var et = {
code: 'et',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Eelnev',
next: 'Järgnev',
today: 'Täna',
month: 'Kuu',
week: 'Nädal',
day: 'Päev',
list: 'Päevakord',
},
weekText: 'näd',
allDayText: 'Kogu päev',
moreLinkText: function(n) {
return '+ veel ' + n
},
noEventsText: 'Kuvamiseks puuduvad sündmused',
};
return et;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var eu = {
code: 'eu',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Aur',
next: 'Hur',
today: 'Gaur',
month: 'Hilabetea',
week: 'Astea',
day: 'Eguna',
list: 'Agenda',
},
weekText: 'As',
allDayText: 'Egun osoa',
moreLinkText: 'gehiago',
noEventsText: 'Ez dago ekitaldirik erakusteko',
};
return eu;
}());

View File

@ -0,0 +1,30 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var fa = {
code: 'fa',
week: {
dow: 6, // Saturday is the first day of the week.
doy: 12, // The week that contains Jan 1st is the first week of the year.
},
direction: 'rtl',
buttonText: {
prev: 'قبلی',
next: 'بعدی',
today: 'امروز',
month: 'ماه',
week: 'هفته',
day: 'روز',
list: 'برنامه',
},
weekText: 'هف',
allDayText: 'تمام روز',
moreLinkText: function(n) {
return 'بیش از ' + n
},
noEventsText: 'هیچ رویدادی به نمایش',
};
return fa;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var fi = {
code: 'fi',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Edellinen',
next: 'Seuraava',
today: 'Tänään',
month: 'Kuukausi',
week: 'Viikko',
day: 'Päivä',
list: 'Tapahtumat',
},
weekText: 'Vk',
allDayText: 'Koko päivä',
moreLinkText: 'lisää',
noEventsText: 'Ei näytettäviä tapahtumia',
};
return fi;
}());

View File

@ -0,0 +1,24 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var frCa = {
code: 'fr',
buttonText: {
prev: 'Précédent',
next: 'Suivant',
today: "Aujourd'hui",
year: 'Année',
month: 'Mois',
week: 'Semaine',
day: 'Jour',
list: 'Mon planning',
},
weekText: 'Sem.',
allDayText: 'Toute la journée',
moreLinkText: 'en plus',
noEventsText: 'Aucun événement à afficher',
};
return frCa;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var frCh = {
code: 'fr-ch',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Précédent',
next: 'Suivant',
today: 'Courant',
year: 'Année',
month: 'Mois',
week: 'Semaine',
day: 'Jour',
list: 'Mon planning',
},
weekText: 'Sm',
allDayText: 'Toute la journée',
moreLinkText: 'en plus',
noEventsText: 'Aucun événement à afficher',
};
return frCh;
}());

View File

@ -0,0 +1,28 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var fr = {
code: 'fr',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Précédent',
next: 'Suivant',
today: "Aujourd'hui",
year: 'Année',
month: 'Mois',
week: 'Semaine',
day: 'Jour',
list: 'Planning',
},
weekText: 'Sem.',
allDayText: 'Toute la journée',
moreLinkText: 'en plus',
noEventsText: 'Aucun événement à afficher',
};
return fr;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var gl = {
code: 'gl',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Ant',
next: 'Seg',
today: 'Hoxe',
month: 'Mes',
week: 'Semana',
day: 'Día',
list: 'Axenda',
},
weekText: 'Sm',
allDayText: 'Todo o día',
moreLinkText: 'máis',
noEventsText: 'Non hai eventos para amosar',
};
return gl;
}());

View File

@ -0,0 +1,24 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var he = {
code: 'he',
direction: 'rtl',
buttonText: {
prev: 'הקודם',
next: 'הבא',
today: 'היום',
month: 'חודש',
week: 'שבוע',
day: 'יום',
list: 'סדר יום',
},
allDayText: 'כל היום',
moreLinkText: 'אחר',
noEventsText: 'אין אירועים להצגה',
weekText: 'שבוע',
};
return he;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var hi = {
code: 'hi',
week: {
dow: 0, // Sunday is the first day of the week.
doy: 6, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'पिछला',
next: 'अगला',
today: 'आज',
month: 'महीना',
week: 'सप्ताह',
day: 'दिन',
list: 'कार्यसूची',
},
weekText: 'हफ्ता',
allDayText: 'सभी दिन',
moreLinkText: function(n) {
return '+अधिक ' + n
},
noEventsText: 'कोई घटनाओं को प्रदर्शित करने के लिए',
};
return hi;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var hr = {
code: 'hr',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Prijašnji',
next: 'Sljedeći',
today: 'Danas',
month: 'Mjesec',
week: 'Tjedan',
day: 'Dan',
list: 'Raspored',
},
weekText: 'Tje',
allDayText: 'Cijeli dan',
moreLinkText: function(n) {
return '+ još ' + n
},
noEventsText: 'Nema događaja za prikaz',
};
return hr;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var hu = {
code: 'hu',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'vissza',
next: 'előre',
today: 'ma',
month: 'Hónap',
week: 'Hét',
day: 'Nap',
list: 'Napló',
},
weekText: 'Hét',
allDayText: 'Egész nap',
moreLinkText: 'további',
noEventsText: 'Nincs megjeleníthető esemény',
};
return hu;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var hyAm = {
code: 'hy-am',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Նախորդ',
next: 'Հաջորդ',
today: 'Այսօր',
month: 'Ամիս',
week: 'Շաբաթ',
day: 'Օր',
list: 'Օրվա ցուցակ',
},
weekText: 'Շաբ',
allDayText: 'Ամբողջ օր',
moreLinkText: function(n) {
return '+ ևս ' + n
},
noEventsText: 'Բացակայում է իրադարձությունը ցուցադրելու',
};
return hyAm;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var id = {
code: 'id',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'mundur',
next: 'maju',
today: 'hari ini',
month: 'Bulan',
week: 'Minggu',
day: 'Hari',
list: 'Agenda',
},
weekText: 'Mg',
allDayText: 'Sehari penuh',
moreLinkText: 'lebih',
noEventsText: 'Tidak ada acara untuk ditampilkan',
};
return id;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var is = {
code: 'is',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Fyrri',
next: 'Næsti',
today: 'Í dag',
month: 'Mánuður',
week: 'Vika',
day: 'Dagur',
list: 'Dagskrá',
},
weekText: 'Vika',
allDayText: 'Allan daginn',
moreLinkText: 'meira',
noEventsText: 'Engir viðburðir til að sýna',
};
return is;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var it = {
code: 'it',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Prec',
next: 'Succ',
today: 'Oggi',
month: 'Mese',
week: 'Settimana',
day: 'Giorno',
list: 'Agenda',
},
weekText: 'Sm',
allDayText: 'Tutto il giorno',
moreLinkText: function(n) {
return '+altri ' + n
},
noEventsText: 'Non ci sono eventi da visualizzare',
};
return it;
}());

View File

@ -0,0 +1,25 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ja = {
code: 'ja',
buttonText: {
prev: '前',
next: '次',
today: '今日',
month: '月',
week: '週',
day: '日',
list: '予定リスト',
},
weekText: '週',
allDayText: '終日',
moreLinkText: function(n) {
return '他 ' + n + ' 件'
},
noEventsText: '表示する予定はありません',
};
return ja;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ka = {
code: 'ka',
week: {
dow: 1,
doy: 7,
},
buttonText: {
prev: 'წინა',
next: 'შემდეგი',
today: 'დღეს',
month: 'თვე',
week: 'კვირა',
day: 'დღე',
list: 'დღის წესრიგი',
},
weekText: 'კვ',
allDayText: 'მთელი დღე',
moreLinkText: function(n) {
return '+ კიდევ ' + n
},
noEventsText: 'ღონისძიებები არ არის',
};
return ka;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var kk = {
code: 'kk',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Алдыңғы',
next: 'Келесі',
today: 'Бүгін',
month: 'Ай',
week: 'Апта',
day: 'Күн',
list: 'Күн тәртібі',
},
weekText: 'Не',
allDayText: 'Күні бойы',
moreLinkText: function(n) {
return '+ тағы ' + n
},
noEventsText: 'Көрсету үшін оқиғалар жоқ',
};
return kk;
}());

View File

@ -0,0 +1,23 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ko = {
code: 'ko',
buttonText: {
prev: '이전달',
next: '다음달',
today: '오늘',
month: '월',
week: '주',
day: '일',
list: '일정목록',
},
weekText: '주',
allDayText: '종일',
moreLinkText: '개',
noEventsText: '일정이 없습니다',
};
return ko;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var lb = {
code: 'lb',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Zréck',
next: 'Weider',
today: 'Haut',
month: 'Mount',
week: 'Woch',
day: 'Dag',
list: 'Terminiwwersiicht',
},
weekText: 'W',
allDayText: 'Ganzen Dag',
moreLinkText: 'méi',
noEventsText: 'Nee Evenementer ze affichéieren',
};
return lb;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var lt = {
code: 'lt',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Atgal',
next: 'Pirmyn',
today: 'Šiandien',
month: 'Mėnuo',
week: 'Savaitė',
day: 'Diena',
list: 'Darbotvarkė',
},
weekText: 'SAV',
allDayText: 'Visą dieną',
moreLinkText: 'daugiau',
noEventsText: 'Nėra įvykių rodyti',
};
return lt;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var lv = {
code: 'lv',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Iepr.',
next: 'Nāk.',
today: 'Šodien',
month: 'Mēnesis',
week: 'Nedēļa',
day: 'Diena',
list: 'Dienas kārtība',
},
weekText: 'Ned.',
allDayText: 'Visu dienu',
moreLinkText: function(n) {
return '+vēl ' + n
},
noEventsText: 'Nav notikumu',
};
return lv;
}());

View File

@ -0,0 +1,25 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var mk = {
code: 'mk',
buttonText: {
prev: 'претходно',
next: 'следно',
today: 'Денес',
month: 'Месец',
week: 'Недела',
day: 'Ден',
list: 'График',
},
weekText: 'Сед',
allDayText: 'Цел ден',
moreLinkText: function(n) {
return '+повеќе ' + n
},
noEventsText: 'Нема настани за прикажување',
};
return mk;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ms = {
code: 'ms',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Sebelum',
next: 'Selepas',
today: 'hari ini',
month: 'Bulan',
week: 'Minggu',
day: 'Hari',
list: 'Agenda',
},
weekText: 'Mg',
allDayText: 'Sepanjang hari',
moreLinkText: function(n) {
return 'masih ada ' + n + ' acara'
},
noEventsText: 'Tiada peristiwa untuk dipaparkan',
};
return ms;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var nb = {
code: 'nb',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Forrige',
next: 'Neste',
today: 'I dag',
month: 'Måned',
week: 'Uke',
day: 'Dag',
list: 'Agenda',
},
weekText: 'Uke',
allDayText: 'Hele dagen',
moreLinkText: 'til',
noEventsText: 'Ingen hendelser å vise',
};
return nb;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ne = {
code: 'ne', // code for nepal
week: {
dow: 7, // Sunday is the first day of the week.
doy: 1, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'अघिल्लो',
next: 'अर्को',
today: 'आज',
month: 'महिना',
week: 'हप्ता',
day: 'दिन',
list: 'सूची',
},
weekText: 'हप्ता',
allDayText: 'दिनभरि',
moreLinkText: 'थप लिंक',
noEventsText: 'देखाउनको लागि कुनै घटनाहरू छैनन्',
};
return ne;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var nl = {
code: 'nl',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Vorige',
next: 'Volgende',
today: 'Vandaag',
year: 'Jaar',
month: 'Maand',
week: 'Week',
day: 'Dag',
list: 'Agenda',
},
allDayText: 'Hele dag',
moreLinkText: 'extra',
noEventsText: 'Geen evenementen om te laten zien',
};
return nl;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var nn = {
code: 'nn',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Førre',
next: 'Neste',
today: 'I dag',
month: 'Månad',
week: 'Veke',
day: 'Dag',
list: 'Agenda',
},
weekText: 'Veke',
allDayText: 'Heile dagen',
moreLinkText: 'til',
noEventsText: 'Ingen hendelser å vise',
};
return nn;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var pl = {
code: 'pl',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Poprzedni',
next: 'Następny',
today: 'Dziś',
month: 'Miesiąc',
week: 'Tydzień',
day: 'Dzień',
list: 'Plan dnia',
},
weekText: 'Tydz',
allDayText: 'Cały dzień',
moreLinkText: 'więcej',
noEventsText: 'Brak wydarzeń do wyświetlenia',
};
return pl;
}());

View File

@ -0,0 +1,25 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ptBr = {
code: 'pt-br',
buttonText: {
prev: 'Anterior',
next: 'Próximo',
today: 'Hoje',
month: 'Mês',
week: 'Semana',
day: 'Dia',
list: 'Lista',
},
weekText: 'Sm',
allDayText: 'dia inteiro',
moreLinkText: function(n) {
return 'mais +' + n
},
noEventsText: 'Não há eventos para mostrar',
};
return ptBr;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var pt = {
code: 'pt',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Anterior',
next: 'Seguinte',
today: 'Hoje',
month: 'Mês',
week: 'Semana',
day: 'Dia',
list: 'Agenda',
},
weekText: 'Sem',
allDayText: 'Todo o dia',
moreLinkText: 'mais',
noEventsText: 'Não há eventos para mostrar',
};
return pt;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ro = {
code: 'ro',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'precedentă',
next: 'următoare',
today: 'Azi',
month: 'Lună',
week: 'Săptămână',
day: 'Zi',
list: 'Agendă',
},
weekText: 'Săpt',
allDayText: 'Toată ziua',
moreLinkText: function(n) {
return '+alte ' + n
},
noEventsText: 'Nu există evenimente de afișat',
};
return ro;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ru = {
code: 'ru',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Пред',
next: 'След',
today: 'Сегодня',
month: 'Месяц',
week: 'Неделя',
day: 'День',
list: 'Повестка дня',
},
weekText: 'Нед',
allDayText: 'Весь день',
moreLinkText: function(n) {
return '+ ещё ' + n
},
noEventsText: 'Нет событий для отображения',
};
return ru;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var sk = {
code: 'sk',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Predchádzajúci',
next: 'Nasledujúci',
today: 'Dnes',
month: 'Mesiac',
week: 'Týždeň',
day: 'Deň',
list: 'Rozvrh',
},
weekText: 'Ty',
allDayText: 'Celý deň',
moreLinkText: function(n) {
return '+ďalšie: ' + n
},
noEventsText: 'Žiadne akcie na zobrazenie',
};
return sk;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var sl = {
code: 'sl',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Prejšnji',
next: 'Naslednji',
today: 'Trenutni',
month: 'Mesec',
week: 'Teden',
day: 'Dan',
list: 'Dnevni red',
},
weekText: 'Teden',
allDayText: 'Ves dan',
moreLinkText: 'več',
noEventsText: 'Ni dogodkov za prikaz',
};
return sl;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var sq = {
code: 'sq',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'mbrapa',
next: 'Përpara',
today: 'sot',
month: 'Muaj',
week: 'Javë',
day: 'Ditë',
list: 'Listë',
},
weekText: 'Ja',
allDayText: 'Gjithë ditën',
moreLinkText: function(n) {
return '+më tepër ' + n
},
noEventsText: 'Nuk ka evente për të shfaqur',
};
return sq;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var srCyrl = {
code: 'sr-cyrl',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Претходна',
next: 'следећи',
today: 'Данас',
month: 'Месец',
week: 'Недеља',
day: 'Дан',
list: 'Планер',
},
weekText: 'Сед',
allDayText: 'Цео дан',
moreLinkText: function(n) {
return '+ још ' + n
},
noEventsText: 'Нема догађаја за приказ',
};
return srCyrl;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var sr = {
code: 'sr',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Prethodna',
next: 'Sledeći',
today: 'Danas',
month: 'Mеsеc',
week: 'Nеdеlja',
day: 'Dan',
list: 'Planеr',
},
weekText: 'Sed',
allDayText: 'Cеo dan',
moreLinkText: function(n) {
return '+ još ' + n
},
noEventsText: 'Nеma događaja za prikaz',
};
return sr;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var sv = {
code: 'sv',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Förra',
next: 'Nästa',
today: 'Idag',
month: 'Månad',
week: 'Vecka',
day: 'Dag',
list: 'Program',
},
weekText: 'v.',
allDayText: 'Heldag',
moreLinkText: 'till',
noEventsText: 'Inga händelser att visa',
};
return sv;
}());

View File

@ -0,0 +1,30 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var th = {
code: 'th',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'ก่อนหน้า',
next: 'ถัดไป',
prevYear: 'ปีก่อนหน้า',
nextYear: 'ปีถัดไป',
year: 'ปี',
today: 'วันนี้',
month: 'เดือน',
week: 'สัปดาห์',
day: 'วัน',
list: 'กำหนดการ',
},
weekText: 'สัปดาห์',
allDayText: 'ตลอดวัน',
moreLinkText: 'เพิ่มเติม',
noEventsText: 'ไม่มีกิจกรรมที่จะแสดง',
};
return th;
}());

View File

@ -0,0 +1,27 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var tr = {
code: 'tr',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'geri',
next: 'ileri',
today: 'bugün',
month: 'Ay',
week: 'Hafta',
day: 'Gün',
list: 'Ajanda',
},
weekText: 'Hf',
allDayText: 'Tüm gün',
moreLinkText: 'daha fazla',
noEventsText: 'Gösterilecek etkinlik yok',
};
return tr;
}());

View File

@ -0,0 +1,17 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var ug = {
code: 'ug',
buttonText: {
month: 'ئاي',
week: 'ھەپتە',
day: 'كۈن',
list: 'كۈنتەرتىپ',
},
allDayText: 'پۈتۈن كۈن',
};
return ug;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var uk = {
code: 'uk',
week: {
dow: 1, // Monday is the first day of the week.
doy: 7, // The week that contains Jan 1st is the first week of the year.
},
buttonText: {
prev: 'Попередній',
next: 'далі',
today: 'Сьогодні',
month: 'Місяць',
week: 'Тиждень',
day: 'День',
list: 'Порядок денний',
},
weekText: 'Тиж',
allDayText: 'Увесь день',
moreLinkText: function(n) {
return '+ще ' + n + '...'
},
noEventsText: 'Немає подій для відображення',
};
return uk;
}());

View File

@ -0,0 +1,21 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var uz = {
code: 'uz',
buttonText: {
month: 'Oy',
week: 'Xafta',
day: 'Kun',
list: 'Kun tartibi',
},
allDayText: "Kun bo'yi",
moreLinkText: function(n) {
return '+ yana ' + n
},
noEventsText: "Ko'rsatish uchun voqealar yo'q",
};
return uz;
}());

View File

@ -0,0 +1,29 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var vi = {
code: 'vi',
week: {
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: 'Trước',
next: 'Tiếp',
today: 'Hôm nay',
month: 'Tháng',
week: 'Tuần',
day: 'Ngày',
list: 'Lịch biểu',
},
weekText: 'Tu',
allDayText: 'Cả ngày',
moreLinkText: function(n) {
return '+ thêm ' + n
},
noEventsText: 'Không có sự kiện để hiển thị',
};
return vi;
}());

View File

@ -0,0 +1,30 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var zhCn = {
code: 'zh-cn',
week: {
// GB/T 7408-1994《数据元和交换格式·信息交换·日期和时间表示法》与ISO 8601:1988等效
dow: 1, // Monday is the first day of the week.
doy: 4, // The week that contains Jan 4th is the first week of the year.
},
buttonText: {
prev: '上月',
next: '下月',
today: '今天',
month: '月',
week: '周',
day: '日',
list: '日程',
},
weekText: '周',
allDayText: '全天',
moreLinkText: function(n) {
return '另外 ' + n + ' 个'
},
noEventsText: '没有事件显示',
};
return zhCn;
}());

View File

@ -0,0 +1,23 @@
FullCalendar.globalLocales.push(function () {
'use strict';
var zhTw = {
code: 'zh-tw',
buttonText: {
prev: '上月',
next: '下月',
today: '今天',
month: '月',
week: '週',
day: '天',
list: '活動列表',
},
weekText: '周',
allDayText: '整天',
moreLinkText: '顯示更多',
noEventsText: '没有任何活動',
};
return zhTw;
}());

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -152,11 +152,16 @@ function enableField(fieldName, enabled, options={}) {
function clearField(fieldName, options={}) { function clearField(fieldName, options={}) {
setFieldValue(fieldName, '', options);
}
function setFieldValue(fieldName, value, options={}) {
var modal = options.modal || '#modal-form'; var modal = options.modal || '#modal-form';
var field = getFieldByName(modal, fieldName); var field = getFieldByName(modal, fieldName);
field.val(""); field.val(value);
} }

View File

@ -152,6 +152,11 @@ class SalesOrderStatus(StatusCode):
PENDING, PENDING,
] ]
# Completed orders
COMPLETE = [
SHIPPED,
]
class StockStatus(StatusCode): class StockStatus(StatusCode):

View File

@ -93,6 +93,7 @@ dynamic_javascript_urls = [
url(r'^barcode.js', DynamicJsView.as_view(template_name='js/barcode.js'), name='barcode.js'), url(r'^barcode.js', DynamicJsView.as_view(template_name='js/barcode.js'), name='barcode.js'),
url(r'^bom.js', DynamicJsView.as_view(template_name='js/bom.js'), name='bom.js'), url(r'^bom.js', DynamicJsView.as_view(template_name='js/bom.js'), name='bom.js'),
url(r'^build.js', DynamicJsView.as_view(template_name='js/build.js'), name='build.js'), url(r'^build.js', DynamicJsView.as_view(template_name='js/build.js'), name='build.js'),
url(r'^calendar.js', DynamicJsView.as_view(template_name='js/calendar.js'), name='calendar.js'),
url(r'^company.js', DynamicJsView.as_view(template_name='js/company.js'), name='company.js'), url(r'^company.js', DynamicJsView.as_view(template_name='js/company.js'), name='company.js'),
url(r'^order.js', DynamicJsView.as_view(template_name='js/order.js'), name='order.js'), url(r'^order.js', DynamicJsView.as_view(template_name='js/order.js'), name='order.js'),
url(r'^part.js', DynamicJsView.as_view(template_name='js/part.js'), name='part.js'), url(r'^part.js', DynamicJsView.as_view(template_name='js/part.js'), name='part.js'),

View File

@ -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):

View File

@ -27,6 +27,8 @@ from InvenTree.helpers import increment, getSetting, normalize
from InvenTree.validators import validate_build_order_reference from InvenTree.validators import validate_build_order_reference
from InvenTree.models import InvenTreeAttachment from InvenTree.models import InvenTreeAttachment
import common.models
import InvenTree.fields import InvenTree.fields
from stock import models as StockModels from stock import models as StockModels
@ -59,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")
@ -819,6 +852,10 @@ class Build(MPTTModel):
location__in=[loc for loc in self.take_from.getUniqueChildren()] location__in=[loc for loc in self.take_from.getUniqueChildren()]
) )
# Exclude expired stock items
if not common.models.InvenTreeSetting.get_setting('STOCK_ALLOW_EXPIRED_BUILD'):
items = items.exclude(StockModels.StockItem.EXPIRED_FILTER)
return items return items
@property @property

View File

@ -28,7 +28,7 @@ class BuildSerializer(InvenTreeModelSerializer):
quantity = serializers.FloatField() quantity = serializers.FloatField()
overdue = serializers.BooleanField() overdue = serializers.BooleanField(required=False, read_only=True)
@staticmethod @staticmethod
def annotate_queryset(queryset): def annotate_queryset(queryset):

View File

@ -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>

View File

@ -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() {

View File

@ -903,6 +903,7 @@ class BuildItemCreate(AjaxCreateView):
if self.build and self.part: if self.build and self.part:
available_items = self.build.availableStockItems(self.part, self.output) available_items = self.build.availableStockItems(self.part, self.output)
form.fields['stock_item'].queryset = available_items form.fields['stock_item'].queryset = available_items
self.available_stock = form.fields['stock_item'].queryset.all() self.available_stock = form.fields['stock_item'].queryset.all()

View File

@ -111,6 +111,20 @@ class InvenTreeSetting(models.Model):
'validator': bool 'validator': bool
}, },
'PART_TEMPLATE': {
'name': _('Template'),
'description': _('Parts are templates by default'),
'default': False,
'validator': bool,
},
'PART_ASSEMBLY': {
'name': _('Assembly'),
'description': _('Parts can be assembled from other components by default'),
'default': False,
'validator': bool,
},
'PART_COMPONENT': { 'PART_COMPONENT': {
'name': _('Component'), 'name': _('Component'),
'description': _('Parts can be used as sub-components by default'), 'description': _('Parts can be used as sub-components by default'),
@ -139,6 +153,42 @@ class InvenTreeSetting(models.Model):
'validator': bool, 'validator': bool,
}, },
'PART_VIRTUAL': {
'name': _('Virtual'),
'description': _('Parts are virtual by default'),
'default': False,
'validator': bool,
},
'STOCK_ENABLE_EXPIRY': {
'name': _('Stock Expiry'),
'description': _('Enable stock expiry functionality'),
'default': False,
'validator': bool,
},
'STOCK_ALLOW_EXPIRED_SALE': {
'name': _('Sell Expired Stock'),
'description': _('Allow sale of expired stock'),
'default': False,
'validator': bool,
},
'STOCK_STALE_DAYS': {
'name': _('Stock Stale Time'),
'description': _('Number of days stock items are considered stale before expiring'),
'default': 0,
'units': _('days'),
'validator': [int],
},
'STOCK_ALLOW_EXPIRED_BUILD': {
'name': _('Build Expired Stock'),
'description': _('Allow building with expired stock'),
'default': False,
'validator': bool,
},
'BUILDORDER_REFERENCE_PREFIX': { 'BUILDORDER_REFERENCE_PREFIX': {
'name': _('Build Order Reference Prefix'), 'name': _('Build Order Reference Prefix'),
'description': _('Prefix value for build order reference'), 'description': _('Prefix value for build order reference'),
@ -338,6 +388,12 @@ class InvenTreeSetting(models.Model):
if setting.is_bool(): if setting.is_bool():
value = InvenTree.helpers.str2bool(value) value = InvenTree.helpers.str2bool(value)
if setting.is_int():
try:
value = int(value)
except (ValueError, TypeError):
value = backup_value
else: else:
value = backup_value value = backup_value
@ -426,18 +482,26 @@ class InvenTreeSetting(models.Model):
return return
# Check if a 'type' has been specified for this value # Boolean validator
if type(validator) == type: if validator == bool:
# Value must "look like" a boolean value
if InvenTree.helpers.is_bool(self.value):
# Coerce into either "True" or "False"
self.value = str(InvenTree.helpers.str2bool(self.value))
else:
raise ValidationError({
'value': _('Value must be a boolean value')
})
if validator == bool: # Integer validator
# Value must "look like" a boolean value if validator == int:
if InvenTree.helpers.is_bool(self.value): try:
# Coerce into either "True" or "False" # Coerce into an integer value
self.value = str(InvenTree.helpers.str2bool(self.value)) self.value = str(int(self.value))
else: except (ValueError, TypeError):
raise ValidationError({ raise ValidationError({
'value': _('Value must be a boolean value') 'value': _('Value must be an integer value'),
}) })
def validate_unique(self, exclude=None): def validate_unique(self, exclude=None):
""" Ensure that the key:value pair is unique. """ Ensure that the key:value pair is unique.
@ -479,6 +543,35 @@ class InvenTreeSetting(models.Model):
return InvenTree.helpers.str2bool(self.value) return InvenTree.helpers.str2bool(self.value)
def is_int(self):
"""
Check if the setting is required to be an integer value:
"""
validator = InvenTreeSetting.get_setting_validator(self.key)
if validator == int:
return True
if type(validator) in [list, tuple]:
for v in validator:
if v == int:
return True
def as_int(self):
"""
Return the value of this setting converted to a boolean value.
If an error occurs, return the default value
"""
try:
value = int(self.value)
except (ValueError, TypeError):
value = self.default_value()
return value
class PriceBreak(models.Model): class PriceBreak(models.Model):
""" """

View File

@ -21,3 +21,11 @@ def currency_code_default():
code = 'USD' code = 'USD'
return code return code
def stock_expiry_enabled():
"""
Returns True if the stock expiry feature is enabled
"""
return InvenTreeSetting.get_setting('STOCK_ENABLE_EXPIRY')

View File

@ -31,7 +31,7 @@ class SettingsTest(TestCase):
# There should be two settings objects in the database # There should be two settings objects in the database
settings = InvenTreeSetting.objects.all() settings = InvenTreeSetting.objects.all()
self.assertEqual(settings.count(), 2) self.assertTrue(settings.count() >= 2)
instance_name = InvenTreeSetting.objects.get(pk=1) instance_name = InvenTreeSetting.objects.get(pk=1)
self.assertEqual(instance_name.key, 'INVENTREE_INSTANCE') self.assertEqual(instance_name.key, 'INVENTREE_INSTANCE')

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -107,6 +107,13 @@ class POList(generics.ListCreateAPIView):
except (ValueError, SupplierPart.DoesNotExist): except (ValueError, SupplierPart.DoesNotExist):
pass pass
# 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 = PurchaseOrder.filterByDate(queryset, min_date, max_date)
return queryset return queryset
filter_backends = [ filter_backends = [
@ -293,6 +300,13 @@ class SOList(generics.ListCreateAPIView):
except (Part.DoesNotExist, ValueError): except (Part.DoesNotExist, ValueError):
pass pass
# 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 = SalesOrder.filterByDate(queryset, min_date, max_date)
return queryset return queryset
filter_backends = [ filter_backends = [

View File

@ -121,6 +121,44 @@ class PurchaseOrder(Order):
received_by: User that received the goods received_by: User that received the goods
""" """
@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
- Determine which "interesting" orders exist bewteen these dates
To be "interesting":
- A "received" order where the received date lies within the date range
- TODO: A "pending" order where the target date lies within the date range
- TODO: An "overdue" order where the target date is in the past
"""
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
# Construct a queryset for "received" orders within the range
received = Q(status=PurchaseOrderStatus.COMPLETE) & Q(complete_date__gte=min_date) & Q(complete_date__lte=max_date)
# TODO - Construct a queryset for "pending" orders within the range
# TODO - Construct a queryset for "overdue" orders within the range
flt = received
queryset = queryset.filter(flt)
return queryset
def __str__(self): def __str__(self):
prefix = getSetting('PURCHASEORDER_REFERENCE_PREFIX') prefix = getSetting('PURCHASEORDER_REFERENCE_PREFIX')
@ -301,6 +339,43 @@ class SalesOrder(Order):
OVERDUE_FILTER = Q(status__in=SalesOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date()) OVERDUE_FILTER = Q(status__in=SalesOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__lte=datetime.now().date())
@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
- Determine which "interesting" orders exist between these dates
To be "interesting":
- A "completed" order where the completion date lies within the date range
- A "pending" order where the target date lies within the date range
- TODO: An "overdue" order where the target date is in the past
"""
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
# Construct a queryset for "completed" orders within the range
completed = Q(status__in=SalesOrderStatus.COMPLETE) & Q(shipment_date__gte=min_date) & Q(shipment_date__lte=max_date)
# Construct a queryset for "pending" orders within the range
pending = Q(status__in=SalesOrderStatus.OPEN) & ~Q(target_date=None) & Q(target_date__gte=min_date) & Q(target_date__lte=max_date)
# TODO: Construct a queryset for "overdue" orders within the range
queryset = queryset.filter(completed | pending)
return queryset
def __str__(self): def __str__(self):
prefix = getSetting('SALESORDER_REFERENCE_PREFIX') prefix = getSetting('SALESORDER_REFERENCE_PREFIX')

View File

@ -181,7 +181,7 @@ class SalesOrderSerializer(InvenTreeModelSerializer):
status_text = serializers.CharField(source='get_status_display', read_only=True) status_text = serializers.CharField(source='get_status_display', read_only=True)
overdue = serializers.BooleanField() overdue = serializers.BooleanField(required=False, read_only=True)
class Meta: class Meta:
model = SalesOrder model = SalesOrder

View File

@ -1,5 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load inventree_extras %}
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
@ -18,6 +19,12 @@ InvenTree | {% trans "Purchase Orders" %}
<button class='btn btn-primary' type='button' id='po-create' title='{% trans "Create new purchase order" %}'> <button class='btn btn-primary' type='button' id='po-create' title='{% trans "Create new purchase order" %}'>
<span class='fas fa-plus-circle'></span> {% trans "New Purchase Order" %}</button> <span class='fas fa-plus-circle'></span> {% trans "New Purchase Order" %}</button>
{% endif %} {% 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-purchaseorder'> <div class='filter-list' id='filter-list-purchaseorder'>
<!-- An empty div in which the filter list will be constructed --> <!-- An empty div in which the filter list will be constructed -->
</div> </div>
@ -27,11 +34,124 @@ InvenTree | {% trans "Purchase Orders" %}
<table class='table table-striped table-condensed po-table' data-toolbar='#table-buttons' id='purchase-order-table'> <table class='table table-striped table-condensed po-table' data-toolbar='#table-buttons' id='purchase-order-table'>
</table> </table>
<div id='purchase-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 purchase orders from the server within specified date range
inventreeGet(
'{% url "api-po-list" %}',
{
supplier_detail: true,
min_date: start,
max_date: end,
},
{
success: function(response) {
var prefix = '{% settings_value "PURCHASEORDER_REFERENCE_PREFIX" %}';
for (var idx = 0; idx < response.length; idx++) {
var order = response[idx];
var date = order.creation_date;
if (order.complete_date) {
date = order.complete_date;
}
var title = `${prefix}${order.reference} - ${order.supplier_detail.name}`;
var color = '#4c68f5';
if (order.complete_date) {
color = '#25c235';
} else if (order.overdue) {
color = '#c22525';
} else {
color = '#4c68f5';
}
var event = {
title: title,
start: date,
end: date,
url: `/order/purchase-order/${order.pk}/`,
backgroundColor: color,
};
calendar.addEvent(event);
}
}
}
);
}
var calendar = null;
document.addEventListener('DOMContentLoaded', function() {
var el = document.getElementById('purchase-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 }}
$('#purchase-order-calendar').hide();
$('#view-list').hide();
$('#view-calendar').click(function() {
// Hide the list view, show the calendar view
$("#purchase-order-table").hide();
$("#view-calendar").hide();
$(".fixed-table-pagination").hide();
$(".columns-right").hide();
$(".search").hide();
$('#filter-list-salesorder').hide();
$("#purchase-order-calendar").show();
$("#view-list").show();
});
$("#view-list").click(function() {
// Hide the calendar view, show the list view
$("#purchase-order-calendar").hide();
$("#view-list").hide();
$(".fixed-table-pagination").show();
$(".columns-right").show();
$(".search").show();
$("#purchase-order-table").show();
$('#filter-list-salesorder').show();
$("#view-calendar").show();
});
$("#po-create").click(function() { $("#po-create").click(function() {
launchModalForm("{% url 'po-create' %}", launchModalForm("{% url 'po-create' %}",
{ {

View File

@ -1,5 +1,6 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load inventree_extras %}
{% load static %} {% load static %}
{% load i18n %} {% load i18n %}
@ -18,6 +19,12 @@ InvenTree | {% trans "Sales Orders" %}
<button class='btn btn-primary' type='button' id='so-create' title='{% trans "Create new sales order" %}'> <button class='btn btn-primary' type='button' id='so-create' title='{% trans "Create new sales order" %}'>
<span class='fas fa-plus-circle'></span> {% trans "New Sales Order" %}</button> <span class='fas fa-plus-circle'></span> {% trans "New Sales Order" %}</button>
{% endif %} {% 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-salesorder'> <div class='filter-list' id='filter-list-salesorder'>
<!-- An empty div in which the filter list will be constructed --> <!-- An empty div in which the filter list will be constructed -->
</div> </div>
@ -27,11 +34,124 @@ InvenTree | {% trans "Sales Orders" %}
<table class='table table-striped table-condensed po-table' data-toolbar='#table-buttons' id='sales-order-table'> <table class='table table-striped table-condensed po-table' data-toolbar='#table-buttons' id='sales-order-table'>
</table> </table>
<div id='sales-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 orders from the server within specified date range
inventreeGet(
'{% url "api-so-list" %}',
{
customer_detail: true,
min_date: start,
max_date: end,
},
{
success: function(response) {
var prefix = '{% settings_value "SALESORDER_REFERENCE_PREFIX" %}';
for (var idx = 0; idx < response.length; idx++) {
var order = response[idx];
var date = order.creation_date;
if (order.shipment_date) {
date = order.shipment_date;
} else if (order.target_date) {
date = order.target_date;
}
var title = `${prefix}${order.reference} - ${order.customer_detail.name}`;
// Default color is blue
var color = '#4c68f5';
// Overdue orders are red
if (order.overdue) {
color = '#c22525';
} else if (order.status == {{ SalesOrderStatus.SHIPPED }}) {
color = '#25c235';
}
var event = {
title: title,
start: date,
end: date,
url: `/order/sales-order/${order.pk}/`,
backgroundColor: color,
};
calendar.addEvent(event);
}
}
}
);
}
var calendar = null;
document.addEventListener('DOMContentLoaded', function() {
var calendarEl = document.getElementById('sales-order-calendar');
calendar = new FullCalendar.Calendar(calendarEl, {
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 }}
$("#sales-order-calendar").hide();
$("#view-list").hide();
$('#view-calendar').click(function() {
// Hide the list view, show the calendar view
$("#sales-order-table").hide();
$("#view-calendar").hide();
$(".fixed-table-pagination").hide();
$(".columns-right").hide();
$(".search").hide();
$('#filter-list-salesorder').hide();
$("#sales-order-calendar").show();
$("#view-list").show();
});
$("#view-list").click(function() {
// Hide the calendar view, show the list view
$("#sales-order-calendar").hide();
$("#view-list").hide();
$(".fixed-table-pagination").show();
$(".columns-right").show();
$(".search").show();
$("#sales-order-table").show();
$('#filter-list-salesorder').show();
$("#view-calendar").show();
});
loadSalesOrderTable("#sales-order-table", { loadSalesOrderTable("#sales-order-table", {
url: "{% url 'api-so-list' %}", url: "{% url 'api-so-list' %}",
}); });

View File

@ -24,6 +24,8 @@ from company.models import Company, SupplierPart
from stock.models import StockItem, StockLocation from stock.models import StockItem, StockLocation
from part.models import Part from part.models import Part
from common.models import InvenTreeSetting
from . import forms as order_forms from . import forms as order_forms
from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView from InvenTree.views import AjaxView, AjaxCreateView, AjaxUpdateView, AjaxDeleteView
@ -1359,7 +1361,8 @@ class SalesOrderAllocationCreate(AjaxCreateView):
try: try:
line = SalesOrderLineItem.objects.get(pk=line_id) line = SalesOrderLineItem.objects.get(pk=line_id)
queryset = form.fields['item'].queryset # Construct a queryset for allowable stock items
queryset = StockItem.objects.filter(StockItem.IN_STOCK_FILTER)
# Ensure the part reference matches # Ensure the part reference matches
queryset = queryset.filter(part=line.part) queryset = queryset.filter(part=line.part)
@ -1369,6 +1372,10 @@ class SalesOrderAllocationCreate(AjaxCreateView):
queryset = queryset.exclude(pk__in=allocated) queryset = queryset.exclude(pk__in=allocated)
# Exclude stock items which have expired
if not InvenTreeSetting.get_setting('STOCK_ALLOW_EXPIRED_SALE'):
queryset = queryset.exclude(StockItem.EXPIRED_FILTER)
form.fields['item'].queryset = queryset form.fields['item'].queryset = queryset
# Hide the 'line' field # Hide the 'line' field

View File

@ -74,6 +74,7 @@
level: 0 level: 0
lft: 0 lft: 0
rght: 0 rght: 0
default_expiry: 10
- model: part.part - model: part.part
pk: 50 pk: 50
@ -134,6 +135,7 @@
fields: fields:
name: 'Red chair' name: 'Red chair'
variant_of: 10000 variant_of: 10000
IPN: "R.CH"
trackable: true trackable: true
category: 7 category: 7
tree_id: 1 tree_id: 1

View File

@ -181,6 +181,7 @@ class EditPartForm(HelperForm):
'keywords': 'fa-key', 'keywords': 'fa-key',
'link': 'fa-link', 'link': 'fa-link',
'IPN': 'fa-hashtag', 'IPN': 'fa-hashtag',
'default_expiry': 'fa-stopwatch',
} }
bom_copy = forms.BooleanField(required=False, bom_copy = forms.BooleanField(required=False,
@ -228,11 +229,16 @@ class EditPartForm(HelperForm):
'link', 'link',
'default_location', 'default_location',
'default_supplier', 'default_supplier',
'default_expiry',
'units', 'units',
'minimum_stock', 'minimum_stock',
'component',
'assembly',
'is_template',
'trackable', 'trackable',
'purchaseable', 'purchaseable',
'salable', 'salable',
'virtual',
] ]

View File

@ -0,0 +1,85 @@
# Generated by Django 3.0.7 on 2021-01-03 12:13
import InvenTree.fields
import InvenTree.validators
from django.db import migrations, models
import django.db.models.deletion
import markdownx.models
import mptt.fields
import part.settings
class Migration(migrations.Migration):
dependencies = [
('stock', '0055_auto_20201117_1453'),
('part', '0060_merge_20201112_1722'),
]
operations = [
migrations.AlterField(
model_name='part',
name='IPN',
field=models.CharField(blank=True, help_text='Internal Part Number', max_length=100, null=True, validators=[InvenTree.validators.validate_part_ipn], verbose_name='IPN'),
),
migrations.AlterField(
model_name='part',
name='assembly',
field=models.BooleanField(default=part.settings.part_assembly_default, help_text='Can this part be built from other parts?', verbose_name='Assembly'),
),
migrations.AlterField(
model_name='part',
name='category',
field=mptt.fields.TreeForeignKey(blank=True, help_text='Part category', null=True, on_delete=django.db.models.deletion.DO_NOTHING, related_name='parts', to='part.PartCategory', verbose_name='Category'),
),
migrations.AlterField(
model_name='part',
name='default_location',
field=mptt.fields.TreeForeignKey(blank=True, help_text='Where is this item normally stored?', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_parts', to='stock.StockLocation', verbose_name='Default Location'),
),
migrations.AlterField(
model_name='part',
name='description',
field=models.CharField(help_text='Part description', max_length=250, verbose_name='Description'),
),
migrations.AlterField(
model_name='part',
name='is_template',
field=models.BooleanField(default=part.settings.part_template_default, help_text='Is this part a template part?', verbose_name='Is Template'),
),
migrations.AlterField(
model_name='part',
name='keywords',
field=models.CharField(blank=True, help_text='Part keywords to improve visibility in search results', max_length=250, null=True, verbose_name='Keywords'),
),
migrations.AlterField(
model_name='part',
name='link',
field=InvenTree.fields.InvenTreeURLField(blank=True, help_text='Link to external URL', null=True, verbose_name='Link'),
),
migrations.AlterField(
model_name='part',
name='name',
field=models.CharField(help_text='Part name', max_length=100, validators=[InvenTree.validators.validate_part_name], verbose_name='Name'),
),
migrations.AlterField(
model_name='part',
name='notes',
field=markdownx.models.MarkdownxField(blank=True, help_text='Part notes - supports Markdown formatting', null=True, verbose_name='Notes'),
),
migrations.AlterField(
model_name='part',
name='revision',
field=models.CharField(blank=True, help_text='Part revision or version number', max_length=100, null=True, verbose_name='Revision'),
),
migrations.AlterField(
model_name='part',
name='variant_of',
field=models.ForeignKey(blank=True, help_text='Is this part a variant of another part?', limit_choices_to={'active': True, 'is_template': True}, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='variants', to='part.Part', verbose_name='Variant Of'),
),
migrations.AlterField(
model_name='part',
name='virtual',
field=models.BooleanField(default=part.settings.part_virtual_default, help_text='Is this a virtual part, such as a software product or license?', verbose_name='Virtual'),
),
]

View File

@ -0,0 +1,36 @@
# Generated by Django 3.0.7 on 2021-01-04 12:31
import django.core.validators
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('company', '0031_auto_20210103_2215'),
('part', '0060_merge_20201112_1722'),
]
operations = [
migrations.AddField(
model_name='part',
name='default_expiry',
field=models.PositiveIntegerField(default=0, help_text='Expiry time (in days) for stock items of this part', validators=[django.core.validators.MinValueValidator(0)], verbose_name='Default Expiry'),
),
migrations.AlterField(
model_name='part',
name='default_supplier',
field=models.ForeignKey(blank=True, help_text='Default supplier part', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='default_parts', to='company.SupplierPart', verbose_name='Default Supplier'),
),
migrations.AlterField(
model_name='part',
name='minimum_stock',
field=models.PositiveIntegerField(default=0, help_text='Minimum allowed stock level', validators=[django.core.validators.MinValueValidator(0)], verbose_name='Minimum Stock'),
),
migrations.AlterField(
model_name='part',
name='units',
field=models.CharField(blank=True, default='', help_text='Stock keeping units for this part', max_length=20, null=True, verbose_name='Units'),
),
]

Some files were not shown because too many files have changed in this diff Show More