- datastore: export/import JSON con le chiavi camelCase dell'app Android (breedSettings/reservations/customers), scorte e ultimo aggiornamento preservati al ripristino - settings: flag 'introduzione vista' - desktop: permesso Documents (dove finisce il backup) - nuovi controlli: tools/check_qml.py (chiavi di traduzione, simboli JS, pagine, componenti) e qmllint nella suite - versione 0.2.0
302 lines
10 KiB
QML
302 lines
10 KiB
QML
import QtQuick 2.2
|
|
import Sailfish.Silica 1.0
|
|
import "../js/henflow.js" as HF
|
|
import "../js/i18n.js" as I18N
|
|
import "../js/catalog.js" as Catalog
|
|
|
|
// Scheda ordine: nuovo ordine o modifica di uno esistente.
|
|
// Porting di AddReservationSheet + _calculateDeliveryDate: la data di consegna
|
|
// viene calcolata dalla coda FIFO e mostrata in anteprima mentre si digita.
|
|
Page {
|
|
id: page
|
|
allowedOrientations: Orientation.All
|
|
|
|
property var reservation: null // null = nuovo ordine
|
|
property var onSaved: null // callback della pagina chiamante (ricarica la Home)
|
|
property var breeds: []
|
|
property var choices: [] // razze attive con galline in deposizione
|
|
property int selected: -1
|
|
property string lang: "en"
|
|
property string errorMsg: ""
|
|
|
|
function tr(key, arg) { return I18N.t(key, arg, page.lang) }
|
|
|
|
function load() {
|
|
page.lang = I18N.langFor(appSettings.language, Qt.locale().name)
|
|
page.breeds = appData.breedSettings()
|
|
|
|
var list = []
|
|
for (var i = 0; i < page.breeds.length; i++) {
|
|
if (HF.activeHens(page.breeds[i]) > 0)
|
|
list.push(page.breeds[i].breedId)
|
|
}
|
|
page.choices = list
|
|
|
|
if (page.reservation) {
|
|
customerField.text = page.reservation.customerName
|
|
eggsField.text = String(page.reservation.eggsRequested)
|
|
for (var j = 0; j < list.length; j++) {
|
|
if (list[j] === page.reservation.breedId)
|
|
page.selected = j
|
|
}
|
|
}
|
|
if (page.selected < 0 && list.length > 0)
|
|
page.selected = 0
|
|
|
|
page.updatePreview()
|
|
}
|
|
|
|
// Data prevista: parte dalle scorte e dalla coda corrente (_calculateDeliveryDate).
|
|
function updatePreview() {
|
|
if (page.selected < 0) {
|
|
previewLabel.text = page.tr("config_breed_first")
|
|
return
|
|
}
|
|
var eggs = parseInt(eggsField.text)
|
|
if (!eggs || eggs <= 0)
|
|
eggs = 0
|
|
|
|
var breedId = page.choices[page.selected]
|
|
var today = HF.todayMidnight()
|
|
var delivery = HF.estimateDeliveryDate(appData.reservations(),
|
|
appData.warehouseStock(),
|
|
page.breeds, Catalog.HF_BREEDS,
|
|
breedId, eggs, today)
|
|
var days = HF.dayDiff(today, HF.parseIso(delivery))
|
|
var when
|
|
if (days <= 0) when = page.tr("today")
|
|
else if (days === 1) when = page.tr("in_day")
|
|
else when = page.tr("in_days", days)
|
|
|
|
previewLabel.text = HF.formatDay(delivery) + " (" + when + ")"
|
|
}
|
|
|
|
function save() {
|
|
if (page.selected < 0) {
|
|
page.errorMsg = page.tr("config_breed_first")
|
|
return
|
|
}
|
|
var name = customerField.text.trim()
|
|
if (name.length === 0) {
|
|
page.errorMsg = page.tr("customer_name")
|
|
return
|
|
}
|
|
var eggs = parseInt(eggsField.text)
|
|
if (!eggs || eggs <= 0) {
|
|
page.errorMsg = page.tr("eggs_req")
|
|
return
|
|
}
|
|
|
|
var breedId = page.choices[page.selected]
|
|
var list = appData.reservations()
|
|
var today = HF.todayMidnight()
|
|
var delivery = HF.estimateDeliveryDate(list, appData.warehouseStock(),
|
|
page.breeds, Catalog.HF_BREEDS,
|
|
breedId, eggs, today)
|
|
|
|
if (page.reservation) {
|
|
for (var i = 0; i < list.length; i++) {
|
|
if (list[i].id === page.reservation.id) {
|
|
list[i].customerName = name
|
|
list[i].breedId = breedId
|
|
list[i].eggsRequested = eggs
|
|
list[i].deliveryDate = delivery
|
|
break
|
|
}
|
|
}
|
|
} else {
|
|
list.push({
|
|
"id": HF.newId(),
|
|
"customerName": name,
|
|
"breedId": breedId,
|
|
"eggsRequested": eggs,
|
|
"createdAt": HF.nowIso(),
|
|
"deliveryDate": delivery,
|
|
"isDelivered": false
|
|
})
|
|
}
|
|
appData.saveReservations(list)
|
|
if (page.onSaved)
|
|
page.onSaved()
|
|
pageStack.pop()
|
|
}
|
|
|
|
SilicaFlickable {
|
|
anchors.fill: parent
|
|
contentHeight: formColumn.height
|
|
|
|
Column {
|
|
id: formColumn
|
|
width: parent.width
|
|
|
|
PageHeader {
|
|
title: page.reservation ? page.tr("edit_order") : page.tr("new_order")
|
|
}
|
|
|
|
TextField {
|
|
id: customerField
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
label: page.tr("customer_name")
|
|
placeholderText: page.tr("customer_name")
|
|
inputMethodHints: Qt.ImhNoPredictiveText
|
|
onTextChanged: page.errorMsg = ""
|
|
}
|
|
|
|
// suggerimenti dai clienti registrati
|
|
Repeater {
|
|
model: {
|
|
var out = []
|
|
var q = customerField.text.toLowerCase()
|
|
if (q.length < 2)
|
|
return 0
|
|
var customers = appData.customers()
|
|
for (var i = 0; i < customers.length && out.length < 3; i++) {
|
|
var full = (customers[i].firstName + " " + customers[i].lastName).trim()
|
|
if (full.toLowerCase().indexOf(q) === 0)
|
|
out.push(full)
|
|
}
|
|
return out.length
|
|
}
|
|
|
|
delegate: BackgroundItem {
|
|
width: formColumn.width
|
|
height: Theme.itemSizeSmall
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
truncationMode: TruncationMode.Fade
|
|
color: parent.highlighted ? Theme.highlightColor : Theme.secondaryColor
|
|
text: page.suggestions(index)
|
|
}
|
|
|
|
onClicked: {
|
|
customerField.text = page.suggestions(index)
|
|
page.errorMsg = ""
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
text: page.tr("breed")
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
color: Theme.secondaryColor
|
|
}
|
|
|
|
Repeater {
|
|
model: page.choices.length
|
|
|
|
delegate: BackgroundItem {
|
|
id: breedRow
|
|
width: formColumn.width
|
|
height: Theme.itemSizeSmall
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
anchors.verticalCenter: parent.verticalCenter
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
truncationMode: TruncationMode.Fade
|
|
color: (index === page.selected)
|
|
? Theme.highlightColor
|
|
: (breedRow.highlighted ? Theme.highlightColor : Theme.primaryColor)
|
|
text: page.breedLabel(page.choices[index])
|
|
+ " · " + page.tr("in_laying") + ": "
|
|
+ HF.activeHens(page.breedIndex(page.choices[index]))
|
|
}
|
|
|
|
onClicked: {
|
|
page.selected = index
|
|
page.updatePreview()
|
|
}
|
|
}
|
|
}
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
visible: page.choices.length === 0
|
|
wrapMode: Text.WordWrap
|
|
text: page.tr("config_breed_first")
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
color: Theme.errorColor
|
|
}
|
|
|
|
TextField {
|
|
id: eggsField
|
|
anchors.left: parent.left
|
|
anchors.right: parent.right
|
|
label: page.tr("eggs_req")
|
|
inputMethodHints: Qt.ImhDigitsOnly
|
|
validator: IntValidator { bottom: 1; top: 9999 }
|
|
onTextChanged: {
|
|
page.errorMsg = ""
|
|
page.updatePreview()
|
|
}
|
|
}
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
text: page.tr("delivery_preview")
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
color: Theme.secondaryColor
|
|
}
|
|
|
|
Label {
|
|
id: previewLabel
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
font.pixelSize: Theme.fontSizeLarge
|
|
color: Theme.highlightColor
|
|
}
|
|
|
|
Label {
|
|
x: Theme.horizontalPageMargin
|
|
width: parent.width - 2 * Theme.horizontalPageMargin
|
|
visible: page.errorMsg.length > 0
|
|
text: page.errorMsg
|
|
wrapMode: Text.WordWrap
|
|
font.pixelSize: Theme.fontSizeExtraSmall
|
|
color: Theme.errorColor
|
|
}
|
|
|
|
Button {
|
|
anchors.horizontalCenter: parent.horizontalCenter
|
|
text: page.tr("save_order")
|
|
onClicked: page.save()
|
|
}
|
|
}
|
|
}
|
|
|
|
function breedLabel(breedId) {
|
|
var c = Catalog.breedFromId(breedId)
|
|
return c ? page.tr(c.name) : breedId
|
|
}
|
|
|
|
function breedIndex(breedId) {
|
|
for (var i = 0; i < page.breeds.length; i++) {
|
|
if (page.breeds[i].breedId === breedId)
|
|
return i
|
|
}
|
|
return -1
|
|
}
|
|
|
|
function suggestions(index) {
|
|
var out = []
|
|
var q = customerField.text.toLowerCase()
|
|
var customers = appData.customers()
|
|
for (var i = 0; i < customers.length && out.length < 3; i++) {
|
|
var full = (customers[i].firstName + " " + customers[i].lastName).trim()
|
|
if (full.toLowerCase().indexOf(q) === 0)
|
|
out.push(full)
|
|
}
|
|
return out[index]
|
|
}
|
|
|
|
Component.onCompleted: page.load()
|
|
}
|