Compare commits

...

2 commits

Author SHA1 Message Date
f8aab05cb7
Bump to 0.8.2
All checks were successful
CI / test (push) Successful in 8m4s
Lint / test (push) Successful in 36s
Trivy / test (push) Successful in 17s
2025-12-31 16:09:29 +11:00
04f67a786f
Add ability to delete an invoice via Manage Invoices dialog 2025-12-31 16:09:16 +11:00
8 changed files with 96 additions and 4 deletions

View file

@ -1,3 +1,7 @@
# 0.8.2
* Add ability to delete an invoice via 'Manage Invoices' dialog
# 0.8.1
* Fix bold/italic/strikethrough styling in certain conditions when toolbar action is used.

View file

@ -2392,6 +2392,18 @@ class DBManager:
(document_id, invoice_id),
)
def delete_invoice(self, invoice_id: int) -> None:
"""Delete an invoice.
Related invoice line items and invoice time log links are removed via
ON DELETE CASCADE.
"""
with self.conn:
self.conn.execute(
"DELETE FROM invoices WHERE id = ?",
(invoice_id,),
)
def time_logs_for_range(
self,
project_id: int,

View file

@ -1065,6 +1065,10 @@ class InvoicesDialog(QDialog):
btn_row = QHBoxLayout()
btn_row.addStretch(1)
delete_btn = QPushButton(strings._("delete"))
delete_btn.clicked.connect(self._on_delete_clicked)
btn_row.addWidget(delete_btn)
close_btn = QPushButton(strings._("close"))
close_btn.clicked.connect(self.accept)
btn_row.addWidget(close_btn)
@ -1073,6 +1077,68 @@ class InvoicesDialog(QDialog):
self._reload_invoices()
# ----------------------------------------------------------------- deletion
def _on_delete_clicked(self) -> None:
"""Delete the currently selected invoice."""
row = self.table.currentRow()
if row < 0:
sel = self.table.selectionModel().selectedRows()
if sel:
row = sel[0].row()
if row < 0:
QMessageBox.information(
self,
strings._("delete"),
strings._("invoice_required"),
)
return
base_item = self.table.item(row, self.COL_NUMBER)
if base_item is None:
return
inv_id = base_item.data(Qt.ItemDataRole.UserRole)
if not inv_id:
return
invoice_number = (base_item.text() or "").strip() or "?"
proj_item = self.table.item(row, self.COL_PROJECT)
project_name = (proj_item.text() if proj_item is not None else "").strip()
label = strings._("delete")
prompt = (
f"{label} '{invoice_number}'"
+ (f" ({project_name})" if project_name else "")
+ "?"
)
resp = QMessageBox.question(
self,
label,
prompt,
QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
QMessageBox.StandardButton.No,
)
if resp != QMessageBox.StandardButton.Yes:
return
# Remove any automatically created due-date reminder.
if self.cfg.reminders:
self._remove_invoice_due_reminder(row, int(inv_id))
try:
self._db.delete_invoice(int(inv_id))
except Exception as e:
QMessageBox.warning(
self,
strings._("error"),
f"Failed to delete invoice: {e}",
)
return
self._reload_invoices()
# ------------------------------------------------------------------ helpers
def _reload_projects(self) -> None:

View file

@ -436,5 +436,6 @@
"invoice_invalid_date_format": "Invalid date format",
"invoice_invalid_tax_rate": "The tax rate is invalid",
"invoice_no_items": "There are no items in the invoice",
"invoice_number_required": "An invoice number is required"
"invoice_number_required": "An invoice number is required",
"invoice_required": "Please select a specific invoice before trying to delete an invoice."
}

View file

@ -432,5 +432,6 @@
"invoice_invalid_date_format": "Format de date invalide",
"invoice_invalid_tax_rate": "Le taux de TVA est invalide",
"invoice_no_items": "La facture ne contient aucun article",
"invoice_number_required": "Un numéro de facture est requis"
"invoice_number_required": "Un numéro de facture est requis",
"invoice_required": "Veuillez sélectionner une facture spécifique avant d'essayer de supprimer la facture."
}

6
debian/changelog vendored
View file

@ -1,3 +1,9 @@
bouquin (0.8.2) unstable; urgency=medium
* Add ability to delete an invoice via 'Manage Invoices' dialog
-- Miguel Jacq <mig@mig5.net> Wed, 31 Dec 2025 16:00:00 +1100
bouquin (0.8.1) unstable; urgency=medium
* Fix bold/italic/strikethrough styling in certain conditions when toolbar action is used.

View file

@ -1,6 +1,6 @@
[tool.poetry]
name = "bouquin"
version = "0.8.1"
version = "0.8.2"
description = "Bouquin is a simple, opinionated notebook application written in Python, PyQt and SQLCipher."
authors = ["Miguel Jacq <mig@mig5.net>"]
readme = "README.md"

View file

@ -4,7 +4,7 @@
# provides the Python distribution/module as "sqlcipher4". To keep Fedora's
# auto-generated python3dist() Requires correct, we rewrite the dependency key in
# pyproject.toml at build time.
%global upstream_version 0.8.1
%global upstream_version 0.8.2
Name: bouquin
Version: %{upstream_version}
@ -82,6 +82,8 @@ install -Dpm 0644 bouquin/icons/bouquin.svg %{buildroot}%{_datadir}/icons/hicolo
%{_datadir}/icons/hicolor/scalable/apps/bouquin.svg
%changelog
* Wed Dec 31 2025 Miguel Jacq <mig@mig5.net> - %{version}-%{release}
- Add ability to delete an invoice via 'Manage Invoices' dialog
* Fri Dec 26 2025 Miguel Jacq <mig@mig5.net> - %{version}-%{release}
- Fix bold/italic/strikethrough styling in certain conditions when toolbar action is used.
- Move a code block or collapsed section (or generally, anything after a checkbox line until the next checkbox line) when moving an unchecked checkbox line to another day.