Compare commits
2 Commits
fa192247fe
...
511e8ebde4
| Author | SHA1 | Date | |
|---|---|---|---|
| 511e8ebde4 | |||
| 1a82776657 |
@@ -133,6 +133,17 @@ class LabelPrintResponse(BaseModel):
|
||||
success: bool
|
||||
message: str
|
||||
|
||||
class NotesVariables(BaseModel):
|
||||
animal_name: str
|
||||
notes: str
|
||||
|
||||
class NotesPrintRequest(BaseModel):
|
||||
variables: NotesVariables
|
||||
|
||||
class NotesPrintResponse(BaseModel):
|
||||
success: bool
|
||||
message: str
|
||||
|
||||
# Authentication Routes
|
||||
@router.post("/auth/register", response_model=TokenResponse)
|
||||
def register(user_data: UserCreate, db: Session = Depends(get_db)):
|
||||
@@ -575,5 +586,66 @@ def print_label(label_request: LabelPrintRequest, current_user: User = Depends(g
|
||||
detail=f"Error sending label print request: {str(e)}"
|
||||
)
|
||||
|
||||
# Notes printing endpoint
|
||||
@router.post("/notes/print", response_model=NotesPrintResponse)
|
||||
def print_notes(notes_request: NotesPrintRequest, current_user: User = Depends(get_current_user)):
|
||||
"""
|
||||
Print notes by publishing an MQTT message
|
||||
|
||||
This endpoint publishes a notes print request to the MQTT broker,
|
||||
which will be picked up by the label printing service.
|
||||
"""
|
||||
try:
|
||||
# Get notes template configuration from environment
|
||||
import os
|
||||
template_id = os.getenv("NOTES_TEMPLATE_ID", "notes_template")
|
||||
label_size = os.getenv("LABEL_SIZE", "29x90")
|
||||
test_mode = os.getenv("LABEL_TEST", "false").lower() == "true"
|
||||
|
||||
# Capitalize text fields for better presentation
|
||||
variables = notes_request.variables.dict()
|
||||
variables["animal_name"] = capitalize_label_text(variables["animal_name"])
|
||||
variables["notes"] = capitalize_label_text(variables["notes"])
|
||||
|
||||
# Convert the request to the MQTT message format
|
||||
mqtt_message = {
|
||||
"template_id": template_id,
|
||||
"label_size": label_size,
|
||||
"variables": variables,
|
||||
"test": test_mode
|
||||
}
|
||||
|
||||
# Publish to MQTT and wait for response
|
||||
success, response = publish_label_print_with_response(mqtt_message, timeout=10.0)
|
||||
|
||||
print(f"Notes print result: success={success}, response={response}")
|
||||
|
||||
if success:
|
||||
result = NotesPrintResponse(
|
||||
success=True,
|
||||
message=response.get("message", "Notes printed successfully")
|
||||
)
|
||||
print(f"Returning success response: {result}")
|
||||
return result
|
||||
else:
|
||||
# Return error details from printer
|
||||
# Check both 'message' and 'error' fields for error details
|
||||
if response:
|
||||
error_msg = response.get("message") or response.get("error", "Unknown error")
|
||||
else:
|
||||
error_msg = "No response from printer"
|
||||
result = NotesPrintResponse(
|
||||
success=False,
|
||||
message=f"Print failed: {error_msg}"
|
||||
)
|
||||
print(f"Returning error response: {result}")
|
||||
return result
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=500,
|
||||
detail=f"Error sending notes print request: {str(e)}"
|
||||
)
|
||||
|
||||
# Include router with /api prefix
|
||||
app.include_router(router)
|
||||
|
||||
@@ -172,14 +172,17 @@ function setupEventListeners() {
|
||||
const dispenseForm = document.getElementById('dispenseForm');
|
||||
const prescribeForm = document.getElementById('prescribeForm');
|
||||
const editForm = document.getElementById('editForm');
|
||||
const printNotesForm = document.getElementById('printNotesForm');
|
||||
const addModal = document.getElementById('addModal');
|
||||
const addVariantModal = document.getElementById('addVariantModal');
|
||||
const editVariantModal = document.getElementById('editVariantModal');
|
||||
const dispenseModal = document.getElementById('dispenseModal');
|
||||
const prescribeModal = document.getElementById('prescribeModal');
|
||||
const editModal = document.getElementById('editModal');
|
||||
const printNotesModal = document.getElementById('printNotesModal');
|
||||
const addDrugBtn = document.getElementById('addDrugBtn');
|
||||
const dispenseBtn = document.getElementById('dispenseBtn');
|
||||
const printNotesBtn = document.getElementById('printNotesBtn');
|
||||
const cancelAddBtn = document.getElementById('cancelAddBtn');
|
||||
const cancelVariantBtn = document.getElementById('cancelVariantBtn');
|
||||
const cancelEditVariantBtn = document.getElementById('cancelEditVariantBtn');
|
||||
@@ -202,8 +205,10 @@ function setupEventListeners() {
|
||||
if (dispenseForm) dispenseForm.addEventListener('submit', handleDispenseDrug);
|
||||
if (prescribeForm) prescribeForm.addEventListener('submit', handlePrescribeDrug);
|
||||
if (editForm) editForm.addEventListener('submit', handleEditDrug);
|
||||
if (printNotesForm) printNotesForm.addEventListener('submit', handlePrintNotes);
|
||||
|
||||
if (addDrugBtn) addDrugBtn.addEventListener('click', () => openModal(addModal));
|
||||
if (printNotesBtn) printNotesBtn.addEventListener('click', () => openModal(printNotesModal));
|
||||
if (dispenseBtn) dispenseBtn.addEventListener('click', () => {
|
||||
updateDispenseDrugSelect();
|
||||
openModal(dispenseModal);
|
||||
@@ -216,6 +221,9 @@ function setupEventListeners() {
|
||||
if (cancelPrescribeBtn) cancelPrescribeBtn.addEventListener('click', () => closeModal(prescribeModal));
|
||||
if (cancelEditBtn) cancelEditBtn.addEventListener('click', closeEditModal);
|
||||
|
||||
const cancelPrintNotesBtn = document.getElementById('cancelPrintNotesBtn');
|
||||
if (cancelPrintNotesBtn) cancelPrintNotesBtn.addEventListener('click', () => closeModal(printNotesModal));
|
||||
|
||||
const closeHistoryBtn = document.getElementById('closeHistoryBtn');
|
||||
if (closeHistoryBtn) closeHistoryBtn.addEventListener('click', () => closeModal(document.getElementById('historyModal')));
|
||||
|
||||
@@ -770,6 +778,63 @@ async function handlePrescribeDrug(e) {
|
||||
}
|
||||
}
|
||||
|
||||
// Handle print notes form submission
|
||||
async function handlePrintNotes(e) {
|
||||
e.preventDefault();
|
||||
|
||||
const animalName = document.getElementById('notesAnimalName').value.trim();
|
||||
const notes = document.getElementById('notesContent').value.trim();
|
||||
|
||||
if (!animalName || !notes) {
|
||||
showToast('Please fill in all required fields', 'warning');
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
// Send notes to print endpoint
|
||||
const notesData = {
|
||||
variables: {
|
||||
animal_name: animalName,
|
||||
notes: notes
|
||||
}
|
||||
};
|
||||
|
||||
const response = await apiCall('/notes/print', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify(notesData)
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const error = await response.json();
|
||||
throw new Error(error.detail || 'Notes printing request failed');
|
||||
}
|
||||
|
||||
const result = await response.json();
|
||||
console.log('Notes print result:', result);
|
||||
|
||||
if (!result.success) {
|
||||
// Printing failed
|
||||
const isError = result.message && (
|
||||
result.message.includes('not found') ||
|
||||
result.message.includes('error') ||
|
||||
result.message.includes('failed')
|
||||
);
|
||||
const toastType = isError ? 'error' : 'warning';
|
||||
showToast(result.message, toastType, 5000);
|
||||
return;
|
||||
}
|
||||
|
||||
// Printing succeeded
|
||||
showToast('Notes printed successfully!', 'success');
|
||||
|
||||
document.getElementById('printNotesForm').reset();
|
||||
closeModal(document.getElementById('printNotesModal'));
|
||||
} catch (error) {
|
||||
console.error('Error printing notes:', error);
|
||||
showToast('Failed to print notes: ' + error.message, 'error');
|
||||
}
|
||||
}
|
||||
|
||||
// Delete variant
|
||||
async function deleteVariant(variantId) {
|
||||
if (!confirm('Are you sure you want to delete this variant?')) return;
|
||||
|
||||
@@ -55,6 +55,7 @@
|
||||
<div class="section-header">
|
||||
<h2>Current Inventory</h2>
|
||||
<div class="header-actions">
|
||||
<button id="printNotesBtn" class="btn btn-primary btn-small">📝 Print Notes</button>
|
||||
<button id="addDrugBtn" class="btn btn-primary btn-small">➕ Add Drug</button>
|
||||
</div>
|
||||
<div class="filters">
|
||||
@@ -429,6 +430,30 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Print Notes Modal -->
|
||||
<div id="printNotesModal" class="modal">
|
||||
<div class="modal-content">
|
||||
<span class="close">×</span>
|
||||
<h2>Print Notes</h2>
|
||||
<form id="printNotesForm" novalidate>
|
||||
<div class="form-group">
|
||||
<label for="notesAnimalName">Animal Name/ID *</label>
|
||||
<input type="text" id="notesAnimalName" required>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="notesContent">Notes *</label>
|
||||
<textarea id="notesContent" rows="6" placeholder="Enter notes to print..." required></textarea>
|
||||
</div>
|
||||
|
||||
<div class="form-actions">
|
||||
<button type="submit" class="btn btn-primary">Print Notes</button>
|
||||
<button type="button" class="btn btn-secondary" id="cancelPrintNotesBtn">Cancel</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="app.js"></script>
|
||||
|
||||
@@ -252,7 +252,9 @@ label {
|
||||
input[type="text"],
|
||||
input[type="number"],
|
||||
input[type="password"],
|
||||
select {
|
||||
input[type="date"],
|
||||
select,
|
||||
textarea {
|
||||
width: 100%;
|
||||
padding: 12px;
|
||||
border: 1px solid var(--border-color);
|
||||
@@ -262,10 +264,17 @@ select {
|
||||
transition: border-color 0.2s;
|
||||
}
|
||||
|
||||
textarea {
|
||||
resize: vertical;
|
||||
min-height: 100px;
|
||||
}
|
||||
|
||||
input[type="text"]:focus,
|
||||
input[type="number"]:focus,
|
||||
input[type="password"]:focus,
|
||||
select:focus {
|
||||
input[type="date"]:focus,
|
||||
select:focus,
|
||||
textarea:focus {
|
||||
outline: none;
|
||||
border-color: var(--secondary-color);
|
||||
box-shadow: 0 0 5px rgba(52, 152, 219, 0.3);
|
||||
|
||||
@@ -12,7 +12,7 @@ password_file /mosquitto/config/pwfile
|
||||
# Logging
|
||||
log_dest stdout
|
||||
log_timestamp true
|
||||
log_type all
|
||||
#log_type all
|
||||
|
||||
# Performance
|
||||
max_connections -1
|
||||
|
||||
Reference in New Issue
Block a user