mirror of
https://github.com/Dvorinka/MyClubServer.git
synced 2026-06-04 10:42:57 +00:00
hot fix #1
This commit is contained in:
@@ -0,0 +1,406 @@
|
||||
-- Create invoice management tables
|
||||
-- Migration: 20250110000002_create_invoice_tables
|
||||
|
||||
-- Invoice settings table
|
||||
CREATE TABLE invoice_settings (
|
||||
id SERIAL PRIMARY KEY,
|
||||
company_name VARCHAR(255) NOT NULL,
|
||||
company_ico VARCHAR(20) NOT NULL,
|
||||
company_dic VARCHAR(20),
|
||||
company_address TEXT,
|
||||
company_city VARCHAR(100),
|
||||
company_zip VARCHAR(10),
|
||||
company_country VARCHAR(100) DEFAULT 'Česká republika',
|
||||
bank_name VARCHAR(255),
|
||||
bank_account VARCHAR(50),
|
||||
bank_iban VARCHAR(50),
|
||||
bank_swift VARCHAR(20),
|
||||
invoice_number_format VARCHAR(100) DEFAULT 'F{year}{seq:6}',
|
||||
next_invoice_number INTEGER DEFAULT 1,
|
||||
current_year INTEGER,
|
||||
default_payment_term INTEGER DEFAULT 14,
|
||||
default_vat_rate DECIMAL(5,2) DEFAULT 21.0,
|
||||
default_currency VARCHAR(3) DEFAULT 'CZK',
|
||||
email_from VARCHAR(255),
|
||||
email_subject VARCHAR(255) DEFAULT 'Faktura č. {invoice_number}',
|
||||
email_body TEXT,
|
||||
pdf_logo_path VARCHAR(500),
|
||||
pdf_footer TEXT,
|
||||
registration_number VARCHAR(50),
|
||||
tax_registration_number VARCHAR(50),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_by INTEGER
|
||||
);
|
||||
|
||||
-- Invoice customers table
|
||||
CREATE TABLE invoice_customers (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
ico VARCHAR(20) UNIQUE,
|
||||
dic VARCHAR(20),
|
||||
address TEXT,
|
||||
city VARCHAR(100),
|
||||
zip VARCHAR(10),
|
||||
country VARCHAR(100) DEFAULT 'Česká republika',
|
||||
email VARCHAR(255),
|
||||
phone VARCHAR(50),
|
||||
website VARCHAR(255),
|
||||
business_type VARCHAR(100),
|
||||
vat_payer BOOLEAN DEFAULT true,
|
||||
notes TEXT,
|
||||
active BOOLEAN DEFAULT true,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by INTEGER,
|
||||
updated_by INTEGER
|
||||
);
|
||||
|
||||
CREATE INDEX idx_invoice_customers_ico ON invoice_customers(ico);
|
||||
CREATE INDEX idx_invoice_customers_active ON invoice_customers(active);
|
||||
CREATE INDEX idx_invoice_customers_name ON invoice_customers(name);
|
||||
|
||||
-- Invoice sequences table
|
||||
CREATE TABLE invoice_sequences (
|
||||
id SERIAL PRIMARY KEY,
|
||||
type VARCHAR(50) NOT NULL,
|
||||
year INTEGER NOT NULL,
|
||||
current_number INTEGER DEFAULT 1,
|
||||
prefix VARCHAR(20),
|
||||
suffix VARCHAR(20),
|
||||
padding INTEGER DEFAULT 6,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE(type, year)
|
||||
);
|
||||
|
||||
-- Insert default sequences
|
||||
INSERT INTO invoice_sequences (type, year, current_number, prefix) VALUES
|
||||
('faktura', EXTRACT(YEAR FROM CURRENT_DATE), 1, 'F'),
|
||||
('zalohova_faktura', EXTRACT(YEAR FROM CURRENT_DATE), 1, 'ZF'),
|
||||
('proforma_faktura', EXTRACT(YEAR FROM CURRENT_DATE), 1, 'PF'),
|
||||
('dobropis', EXTRACT(YEAR FROM CURRENT_DATE), 1, 'D');
|
||||
|
||||
-- Invoice templates table
|
||||
CREATE TABLE invoice_templates (
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
type VARCHAR(50) NOT NULL,
|
||||
description TEXT,
|
||||
header_html TEXT,
|
||||
body_html TEXT,
|
||||
footer_html TEXT,
|
||||
css TEXT,
|
||||
default_vat_rate DECIMAL(5,2) DEFAULT 21.0,
|
||||
default_payment_term INTEGER DEFAULT 14,
|
||||
active BOOLEAN DEFAULT true,
|
||||
default BOOLEAN DEFAULT false,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by INTEGER,
|
||||
updated_by INTEGER
|
||||
);
|
||||
|
||||
-- Invoices table
|
||||
CREATE TABLE invoices (
|
||||
id SERIAL PRIMARY KEY,
|
||||
invoice_number VARCHAR(50) NOT NULL UNIQUE,
|
||||
invoice_type VARCHAR(20) DEFAULT 'faktura',
|
||||
variable_symbol VARCHAR(20),
|
||||
constant_symbol VARCHAR(20),
|
||||
specific_symbol VARCHAR(20),
|
||||
issue_date TIMESTAMP NOT NULL,
|
||||
due_date TIMESTAMP NOT NULL,
|
||||
taxable_supply_date TIMESTAMP,
|
||||
|
||||
-- Supplier information (auto-filled)
|
||||
supplier_name VARCHAR(255) NOT NULL,
|
||||
supplier_ico VARCHAR(20),
|
||||
supplier_dic VARCHAR(20),
|
||||
supplier_address TEXT,
|
||||
supplier_city VARCHAR(100),
|
||||
supplier_zip VARCHAR(10),
|
||||
supplier_country VARCHAR(100) DEFAULT 'Česká republika',
|
||||
|
||||
-- Supplier bank information
|
||||
bank_name VARCHAR(255),
|
||||
bank_account VARCHAR(50),
|
||||
bank_iban VARCHAR(50),
|
||||
bank_swift VARCHAR(20),
|
||||
|
||||
-- Customer information
|
||||
customer_id INTEGER REFERENCES invoice_customers(id),
|
||||
customer_name VARCHAR(255) NOT NULL,
|
||||
customer_ico VARCHAR(20),
|
||||
customer_dic VARCHAR(20),
|
||||
customer_address TEXT,
|
||||
customer_city VARCHAR(100),
|
||||
customer_zip VARCHAR(10),
|
||||
customer_country VARCHAR(100) DEFAULT 'Česká republika',
|
||||
customer_email VARCHAR(255),
|
||||
customer_phone VARCHAR(50),
|
||||
|
||||
-- Financial summary
|
||||
total_amount DECIMAL(15,2) NOT NULL,
|
||||
total_vat DECIMAL(15,2) NOT NULL,
|
||||
total_amount_vat DECIMAL(15,2) NOT NULL,
|
||||
total_amount_without_vat DECIMAL(15,2) NOT NULL,
|
||||
currency VARCHAR(3) DEFAULT 'CZK',
|
||||
|
||||
-- Status and workflow
|
||||
status VARCHAR(20) DEFAULT 'draft',
|
||||
payment_status VARCHAR(20) DEFAULT 'unpaid',
|
||||
payment_date TIMESTAMP,
|
||||
paid_amount DECIMAL(15,2) DEFAULT 0,
|
||||
|
||||
-- Additional information
|
||||
note TEXT,
|
||||
payment_note TEXT,
|
||||
internal_note TEXT,
|
||||
|
||||
-- PDF and sending
|
||||
pdf_path VARCHAR(500),
|
||||
pdf_generated_at TIMESTAMP,
|
||||
sent_at TIMESTAMP,
|
||||
sent_to TEXT,
|
||||
|
||||
-- Metadata
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by INTEGER,
|
||||
updated_by INTEGER
|
||||
);
|
||||
|
||||
CREATE INDEX idx_invoices_invoice_number ON invoices(invoice_number);
|
||||
CREATE INDEX idx_invoices_status ON invoices(status);
|
||||
CREATE INDEX idx_invoices_payment_status ON invoices(payment_status);
|
||||
CREATE INDEX idx_invoices_customer_id ON invoices(customer_id);
|
||||
CREATE INDEX idx_invoices_issue_date ON invoices(issue_date);
|
||||
CREATE INDEX idx_invoices_due_date ON invoices(due_date);
|
||||
CREATE INDEX idx_invoices_customer_ico ON invoices(customer_ico);
|
||||
|
||||
-- Invoice items table
|
||||
CREATE TABLE invoice_items (
|
||||
id SERIAL PRIMARY KEY,
|
||||
invoice_id INTEGER NOT NULL REFERENCES invoices(id) ON DELETE CASCADE,
|
||||
description TEXT NOT NULL,
|
||||
quantity DECIMAL(12,3) NOT NULL,
|
||||
unit VARCHAR(20) DEFAULT 'ks',
|
||||
unit_price DECIMAL(15,2) NOT NULL,
|
||||
total_price DECIMAL(15,2) NOT NULL,
|
||||
vat_rate DECIMAL(5,2) NOT NULL,
|
||||
vat_amount DECIMAL(15,2) NOT NULL,
|
||||
total_with_vat DECIMAL(15,2) NOT NULL,
|
||||
code VARCHAR(100),
|
||||
note TEXT,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE INDEX idx_invoice_items_invoice_id ON invoice_items(invoice_id);
|
||||
|
||||
-- Invoice payments table
|
||||
CREATE TABLE invoice_payments (
|
||||
id SERIAL PRIMARY KEY,
|
||||
invoice_id INTEGER NOT NULL REFERENCES invoices(id) ON DELETE CASCADE,
|
||||
amount DECIMAL(15,2) NOT NULL,
|
||||
currency VARCHAR(3) DEFAULT 'CZK',
|
||||
payment_date TIMESTAMP NOT NULL,
|
||||
payment_method VARCHAR(50),
|
||||
variable_symbol VARCHAR(20),
|
||||
constant_symbol VARCHAR(20),
|
||||
specific_symbol VARCHAR(20),
|
||||
bank_account VARCHAR(50),
|
||||
note TEXT,
|
||||
reference_number VARCHAR(255),
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
created_by INTEGER
|
||||
);
|
||||
|
||||
CREATE INDEX idx_invoice_payments_invoice_id ON invoice_payments(invoice_id);
|
||||
CREATE INDEX idx_invoice_payments_payment_date ON invoice_payments(payment_date);
|
||||
|
||||
-- Insert default invoice settings
|
||||
INSERT INTO invoice_settings (
|
||||
company_name,
|
||||
company_ico,
|
||||
company_dic,
|
||||
company_address,
|
||||
company_city,
|
||||
company_zip,
|
||||
company_country,
|
||||
bank_name,
|
||||
bank_account,
|
||||
bank_iban,
|
||||
bank_swift,
|
||||
invoice_number_format,
|
||||
next_invoice_number,
|
||||
current_year,
|
||||
default_payment_term,
|
||||
default_vat_rate,
|
||||
default_currency,
|
||||
email_subject,
|
||||
registration_number,
|
||||
tax_registration_number
|
||||
) VALUES (
|
||||
'Fotbalový klub',
|
||||
'12345678',
|
||||
'CZ12345678',
|
||||
'Sportovní 1',
|
||||
'Praha',
|
||||
'11000',
|
||||
'Česká republika',
|
||||
'Česká spořitelna',
|
||||
'123456789/0800',
|
||||
'CZ650800000000123456789',
|
||||
'GIBACZPX',
|
||||
'F{year}{seq:6}',
|
||||
1,
|
||||
EXTRACT(YEAR FROM CURRENT_DATE)::INTEGER,
|
||||
14,
|
||||
21.0,
|
||||
'CZK',
|
||||
'Faktura č. {invoice_number}',
|
||||
'Spisová značka: 12345',
|
||||
'DIČ: CZ12345678'
|
||||
);
|
||||
|
||||
-- Insert default invoice template
|
||||
INSERT INTO invoice_templates (
|
||||
name,
|
||||
type,
|
||||
description,
|
||||
header_html,
|
||||
body_html,
|
||||
footer_html,
|
||||
css,
|
||||
default_vat_rate,
|
||||
default_payment_term,
|
||||
active,
|
||||
default
|
||||
) VALUES (
|
||||
'Standardní faktura',
|
||||
'standard',
|
||||
'Standardní šablona pro faktury',
|
||||
'<div class="invoice-header">
|
||||
<div class="logo">
|
||||
<img src="{logo_url}" alt="Logo" />
|
||||
</div>
|
||||
<div class="supplier-info">
|
||||
<h2>{supplier_name}</h2>
|
||||
<p>{supplier_address}</p>
|
||||
<p>{supplier_zip} {supplier_city}</p>
|
||||
<p>IČO: {supplier_ico}</p>
|
||||
{supplier_dic ? `<p>DIČ: {supplier_dic}</p>` : ''}
|
||||
</div>
|
||||
<div class="invoice-info">
|
||||
<h1>Faktura</h1>
|
||||
<p>Číslo: {invoice_number}</p>
|
||||
<p>Datum vydání: {issue_date}</p>
|
||||
<p>Datum splatnosti: {due_date}</p>
|
||||
<p> Datum zdanitelného plnění: {taxable_supply_date}</p>
|
||||
</div>
|
||||
</div>',
|
||||
'<div class="invoice-body">
|
||||
<div class="customer-info">
|
||||
<h3>Odběratel</h3>
|
||||
<p><strong>{customer_name}</strong></p>
|
||||
{customer_ico ? `<p>IČO: {customer_ico}</p>` : ''}
|
||||
{customer_dic ? `<p>DIČ: {customer_dic}</p>` : ''}
|
||||
<p>{customer_address}</p>
|
||||
<p>{customer_zip} {customer_city}</p>
|
||||
{customer_country !== 'Česká republika' ? `<p>{customer_country}</p>` : ''}
|
||||
</div>
|
||||
<div class="invoice-items">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Položka</th>
|
||||
<th>Množství</th>
|
||||
<th>Jedn. cena</th>
|
||||
<th>DPH %</th>
|
||||
<th>Celkem</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{items}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="invoice-summary">
|
||||
<table>
|
||||
<tr>
|
||||
<td>Celkem bez DPH:</td>
|
||||
<td class="amount">{total_amount_without_vat}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>DPH {total_vat_rate}%:</td>
|
||||
<td class="amount">{total_vat}</td>
|
||||
</tr>
|
||||
<tr class="total">
|
||||
<td>Celkem k úhradě:</td>
|
||||
<td class="amount">{total_amount_vat}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>',
|
||||
'<div class="invoice-footer">
|
||||
<div class="payment-info">
|
||||
<h3>Platební údaje</h3>
|
||||
<p><strong>Banka:</strong> {bank_name}</p>
|
||||
<p><strong>Číslo účtu:</strong> {bank_account}</p>
|
||||
<p><strong>IBAN:</strong> {bank_iban}</p>
|
||||
<p><strong>SWIFT:</strong> {bank_swift}</p>
|
||||
{variable_symbol ? `<p><strong>Var. symbol:</strong> {variable_symbol}</p>` : ''}
|
||||
{constant_symbol ? `<p><strong>Konst. symbol:</strong> {constant_symbol}</p>` : ''}
|
||||
</div>
|
||||
<div class="notes">
|
||||
{payment_note ? `<p><strong>Poznámka:</strong> {payment_note}</p>` : ''}
|
||||
{note ? `<p>{note}</p>` : ''}
|
||||
</div>
|
||||
<div class="signature">
|
||||
<p>Vystavil:</p>
|
||||
<div class="signature-line"></div>
|
||||
</div>
|
||||
</div>',
|
||||
'body { font-family: Arial, sans-serif; margin: 0; padding: 20px; }
|
||||
.invoice-header { display: flex; justify-content: space-between; margin-bottom: 40px; }
|
||||
.logo img { max-height: 80px; }
|
||||
.invoice-info { text-align: right; }
|
||||
.invoice-info h1 { margin: 0; font-size: 24px; }
|
||||
.invoice-body { margin-bottom: 40px; }
|
||||
.customer-info { margin-bottom: 30px; }
|
||||
.invoice-items table { width: 100%; border-collapse: collapse; margin-bottom: 20px; }
|
||||
.invoice-items th, .invoice-items td { border: 1px solid #ddd; padding: 8px; text-align: left; }
|
||||
.invoice-items th { background-color: #f5f5f5; }
|
||||
.invoice-items .amount { text-align: right; }
|
||||
.invoice-summary table { width: 300px; margin-left: auto; }
|
||||
.invoice-summary td { padding: 5px; }
|
||||
.invoice-summary .total { font-weight: bold; border-top: 2px solid #333; }
|
||||
.invoice-footer { margin-top: 40px; }
|
||||
.payment-info { margin-bottom: 20px; }
|
||||
.signature-line { border-bottom: 1px solid #333; width: 200px; margin-top: 40px; }',
|
||||
21.0,
|
||||
14,
|
||||
true,
|
||||
true
|
||||
);
|
||||
|
||||
-- Create trigger to update updated_at column
|
||||
CREATE OR REPLACE FUNCTION update_updated_at_column()
|
||||
RETURNS TRIGGER AS $$
|
||||
BEGIN
|
||||
NEW.updated_at = CURRENT_TIMESTAMP;
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$ language 'plpgsql';
|
||||
|
||||
-- Apply the trigger to all invoice tables
|
||||
CREATE TRIGGER update_invoice_settings_updated_at BEFORE UPDATE ON invoice_settings FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_invoice_customers_updated_at BEFORE UPDATE ON invoice_customers FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_invoice_sequences_updated_at BEFORE UPDATE ON invoice_sequences FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_invoice_templates_updated_at BEFORE UPDATE ON invoice_templates FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_invoices_updated_at BEFORE UPDATE ON invoices FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_invoice_items_updated_at BEFORE UPDATE ON invoice_items FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
CREATE TRIGGER update_invoice_payments_updated_at BEFORE UPDATE ON invoice_payments FOR EACH ROW EXECUTE FUNCTION update_updated_at_column();
|
||||
Reference in New Issue
Block a user