Compare commits
No commits in common. "f1534e6cd2f1e9adc614544849ec6c2f04c1cde0" and "4ae9fc5cfa2ce273d53813ae07df5d19b0b7120e" have entirely different histories.
f1534e6cd2
...
4ae9fc5cfa
|
@ -663,10 +663,9 @@ func HandleBatchExpenseAction(w http.ResponseWriter, r *http.Request, _ httprout
|
||||||
}
|
}
|
||||||
entries := mustCollectExpenseEntries(r.Context(), conn, locale, filters)
|
entries := mustCollectExpenseEntries(r.Context(), conn, locale, filters)
|
||||||
vatin := mustCollectExpenseEntriesVATIN(r.Context(), conn, entries)
|
vatin := mustCollectExpenseEntriesVATIN(r.Context(), conn, entries)
|
||||||
lastPaymentDate := mustCollectExpenseEntriesLastPaymentDate(r.Context(), conn, entries)
|
|
||||||
taxes := mustCollectExpenseEntriesTaxes(r.Context(), conn, entries)
|
taxes := mustCollectExpenseEntriesTaxes(r.Context(), conn, entries)
|
||||||
taxColumns := mustCollectTaxColumns(r.Context(), conn, company)
|
taxColumns := mustCollectTaxColumns(r.Context(), conn, company)
|
||||||
ods := mustWriteExpensesOds(entries, vatin, lastPaymentDate, taxes, taxColumns, locale, company)
|
ods := mustWriteExpensesOds(entries, vatin, taxes, taxColumns, locale, company)
|
||||||
writeOdsResponse(w, ods, gettext("expenses.ods", locale))
|
writeOdsResponse(w, ods, gettext("expenses.ods", locale))
|
||||||
default:
|
default:
|
||||||
http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest)
|
http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest)
|
||||||
|
@ -701,20 +700,6 @@ func mustCollectExpenseEntriesVATIN(ctx context.Context, conn *Conn, entries []*
|
||||||
`)
|
`)
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustCollectExpenseEntriesLastPaymentDate(ctx context.Context, conn *Conn, entries []*ExpenseEntry) map[int]time.Time {
|
|
||||||
ids := mustMakeIDArray(entries, func(entry *ExpenseEntry) int {
|
|
||||||
return entry.ID
|
|
||||||
})
|
|
||||||
return mustMakeDateMap(ctx, conn, ids, `
|
|
||||||
select expense_id
|
|
||||||
, max(payment_date)
|
|
||||||
from expense_payment
|
|
||||||
join payment using (payment_id)
|
|
||||||
where expense_id = any ($1)
|
|
||||||
group by expense_id
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func handleRemoveExpense(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
func handleRemoveExpense(w http.ResponseWriter, r *http.Request, params httprouter.Params) {
|
||||||
slug := params[0].Value
|
slug := params[0].Value
|
||||||
if !ValidUuid(slug) {
|
if !ValidUuid(slug) {
|
||||||
|
|
|
@ -673,10 +673,9 @@ func HandleBatchInvoiceAction(w http.ResponseWriter, r *http.Request, _ httprout
|
||||||
}
|
}
|
||||||
entries := mustCollectInvoiceEntries(r.Context(), conn, locale, filters)
|
entries := mustCollectInvoiceEntries(r.Context(), conn, locale, filters)
|
||||||
vatin := mustCollectInvoiceEntriesVATIN(r.Context(), conn, entries)
|
vatin := mustCollectInvoiceEntriesVATIN(r.Context(), conn, entries)
|
||||||
lastCollectionDate := mustCollectInvoiceEntriesLastCollectionDate(r.Context(), conn, entries)
|
|
||||||
taxes := mustCollectInvoiceEntriesTaxes(r.Context(), conn, entries)
|
taxes := mustCollectInvoiceEntriesTaxes(r.Context(), conn, entries)
|
||||||
taxColumns := mustCollectTaxColumns(r.Context(), conn, company)
|
taxColumns := mustCollectTaxColumns(r.Context(), conn, company)
|
||||||
ods := mustWriteInvoicesOds(entries, vatin, lastCollectionDate, taxes, taxColumns, locale, company)
|
ods := mustWriteInvoicesOds(entries, vatin, taxes, taxColumns, locale, company)
|
||||||
writeOdsResponse(w, ods, gettext("invoices.ods", locale))
|
writeOdsResponse(w, ods, gettext("invoices.ods", locale))
|
||||||
default:
|
default:
|
||||||
http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest)
|
http.Error(w, gettext("Invalid action", locale), http.StatusBadRequest)
|
||||||
|
@ -807,43 +806,6 @@ func mustMakeVATINMap(ctx context.Context, conn *Conn, ids *pgtype.Int4Array, sq
|
||||||
return vatin
|
return vatin
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustCollectInvoiceEntriesLastCollectionDate(ctx context.Context, conn *Conn, entries []*InvoiceEntry) map[int]time.Time {
|
|
||||||
ids := mustMakeIDArray(entries, func(entry *InvoiceEntry) int {
|
|
||||||
return entry.ID
|
|
||||||
})
|
|
||||||
return mustMakeDateMap(ctx, conn, ids, `
|
|
||||||
select invoice_id
|
|
||||||
, max(collection_date)
|
|
||||||
from invoice_collection
|
|
||||||
join collection using (collection_id)
|
|
||||||
where invoice_id = any ($1)
|
|
||||||
group by invoice_id
|
|
||||||
`)
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustMakeDateMap(ctx context.Context, conn *Conn, ids *pgtype.Int4Array, sql string) map[int]time.Time {
|
|
||||||
rows, err := conn.Query(ctx, sql, ids)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
defer rows.Close()
|
|
||||||
|
|
||||||
dates := make(map[int]time.Time)
|
|
||||||
for rows.Next() {
|
|
||||||
var entryID int
|
|
||||||
var date time.Time
|
|
||||||
if err := rows.Scan(&entryID, &date); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
dates[entryID] = date
|
|
||||||
}
|
|
||||||
if rows.Err() != nil {
|
|
||||||
panic(rows.Err())
|
|
||||||
}
|
|
||||||
return dates
|
|
||||||
}
|
|
||||||
|
|
||||||
func mustWriteInvoicesPdf(r *http.Request, slugs []string) []byte {
|
func mustWriteInvoicesPdf(r *http.Request, slugs []string) []byte {
|
||||||
conn := getConn(r)
|
conn := getConn(r)
|
||||||
company := mustGetCompany(r)
|
company := mustGetCompany(r)
|
||||||
|
|
31
pkg/ods.go
31
pkg/ods.go
|
@ -53,16 +53,15 @@ func extractTaxIDs(taxColumns map[int]string) []int {
|
||||||
return taxIDs
|
return taxIDs
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustWriteInvoicesOds(invoices []*InvoiceEntry, vatin map[int]string, lastCollectionDate map[int]time.Time, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte {
|
func mustWriteInvoicesOds(invoices []*InvoiceEntry, vatin map[int]string, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte {
|
||||||
taxIDs := extractTaxIDs(taxColumns)
|
taxIDs := extractTaxIDs(taxColumns)
|
||||||
columns := make([]string, 8+len(taxIDs))
|
columns := make([]string, 7+len(taxIDs))
|
||||||
columns[0] = "Date"
|
columns[0] = "Date"
|
||||||
columns[1] = "Invoice Num."
|
columns[1] = "Invoice Num."
|
||||||
columns[2] = "Customer"
|
columns[2] = "Customer"
|
||||||
columns[3] = pgettext("title", "VAT number", locale)
|
columns[3] = pgettext("title", "VAT number", locale)
|
||||||
columns[4] = "Payment Date"
|
columns[4] = "Status"
|
||||||
columns[5] = "Status"
|
i := 5
|
||||||
i := 6
|
|
||||||
for _, taxID := range taxIDs {
|
for _, taxID := range taxIDs {
|
||||||
columns[i] = taxColumns[taxID]
|
columns[i] = taxColumns[taxID]
|
||||||
i++
|
i++
|
||||||
|
@ -74,11 +73,6 @@ func mustWriteInvoicesOds(invoices []*InvoiceEntry, vatin map[int]string, lastCo
|
||||||
writeCellString(sb, invoice.Number)
|
writeCellString(sb, invoice.Number)
|
||||||
writeCellString(sb, invoice.CustomerName)
|
writeCellString(sb, invoice.CustomerName)
|
||||||
writeCellString(sb, vatin[invoice.ID])
|
writeCellString(sb, vatin[invoice.ID])
|
||||||
if date, ok := lastCollectionDate[invoice.ID]; ok {
|
|
||||||
writeCellDate(sb, date)
|
|
||||||
} else {
|
|
||||||
writeCellString(sb, "")
|
|
||||||
}
|
|
||||||
writeCellString(sb, invoice.StatusLabel)
|
writeCellString(sb, invoice.StatusLabel)
|
||||||
writeTaxes(sb, taxes[invoice.ID], taxIDs, locale, company)
|
writeTaxes(sb, taxes[invoice.ID], taxIDs, locale, company)
|
||||||
writeCellFloat(sb, invoice.Total, locale, company)
|
writeCellFloat(sb, invoice.Total, locale, company)
|
||||||
|
@ -105,17 +99,16 @@ func mustWriteQuotesOds(quotes []*QuoteEntry, locale *Locale, company *Company)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func mustWriteExpensesOds(expenses []*ExpenseEntry, vatin map[int]string, lastPaymentDate map[int]time.Time, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte {
|
func mustWriteExpensesOds(expenses []*ExpenseEntry, vatin map[int]string, taxes map[int]taxMap, taxColumns map[int]string, locale *Locale, company *Company) []byte {
|
||||||
taxIDs := extractTaxIDs(taxColumns)
|
taxIDs := extractTaxIDs(taxColumns)
|
||||||
columns := make([]string, 9+len(taxIDs))
|
columns := make([]string, 8+len(taxIDs))
|
||||||
columns[0] = "Contact"
|
columns[0] = "Contact"
|
||||||
columns[1] = pgettext("title", "VAT number", locale)
|
columns[1] = pgettext("title", "VAT number", locale)
|
||||||
columns[2] = "Invoice Date"
|
columns[2] = "Invoice Date"
|
||||||
columns[3] = "Invoice Number"
|
columns[3] = "Invoice Number"
|
||||||
columns[4] = "Payment Date"
|
columns[4] = "Status"
|
||||||
columns[5] = "Status"
|
columns[5] = "Amount"
|
||||||
columns[6] = "Amount"
|
i := 6
|
||||||
i := 7
|
|
||||||
for _, taxID := range taxIDs {
|
for _, taxID := range taxIDs {
|
||||||
columns[i] = taxColumns[taxID]
|
columns[i] = taxColumns[taxID]
|
||||||
i++
|
i++
|
||||||
|
@ -123,15 +116,11 @@ func mustWriteExpensesOds(expenses []*ExpenseEntry, vatin map[int]string, lastPa
|
||||||
columns[i] = "Total"
|
columns[i] = "Total"
|
||||||
columns[i+1] = "Tags"
|
columns[i+1] = "Tags"
|
||||||
return mustWriteTableOds(expenses, columns, locale, func(sb *strings.Builder, expense *ExpenseEntry) {
|
return mustWriteTableOds(expenses, columns, locale, func(sb *strings.Builder, expense *ExpenseEntry) {
|
||||||
|
|
||||||
writeCellString(sb, expense.InvoicerName)
|
writeCellString(sb, expense.InvoicerName)
|
||||||
writeCellString(sb, vatin[expense.ID])
|
writeCellString(sb, vatin[expense.ID])
|
||||||
writeCellDate(sb, expense.InvoiceDate)
|
writeCellDate(sb, expense.InvoiceDate)
|
||||||
writeCellString(sb, expense.InvoiceNumber)
|
writeCellString(sb, expense.InvoiceNumber)
|
||||||
if date, ok := lastPaymentDate[expense.ID]; ok {
|
|
||||||
writeCellDate(sb, date)
|
|
||||||
} else {
|
|
||||||
writeCellString(sb, "")
|
|
||||||
}
|
|
||||||
writeCellString(sb, expense.StatusLabel)
|
writeCellString(sb, expense.StatusLabel)
|
||||||
writeCellFloat(sb, expense.Amount, locale, company)
|
writeCellFloat(sb, expense.Amount, locale, company)
|
||||||
writeTaxes(sb, taxes[expense.ID], taxIDs, locale, company)
|
writeTaxes(sb, taxes[expense.ID], taxIDs, locale, company)
|
||||||
|
|
|
@ -314,7 +314,6 @@ header nav a[aria-current] {
|
||||||
main {
|
main {
|
||||||
padding: 2rem 3rem;
|
padding: 2rem 3rem;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
flex: 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.input {
|
.input {
|
||||||
|
|
Loading…
Reference in New Issue