This commit is contained in:
Mateusz Gruszczyński
2026-03-13 11:03:13 +01:00
commit 35571df778
132 changed files with 11197 additions and 0 deletions

View File

View File

@@ -0,0 +1,108 @@
from datetime import date, timedelta
from sqlalchemy import Integer, extract, or_, func, cast
from app.models.invoice import Invoice, InvoiceStatus, InvoiceType
from app.services.company_service import CompanyService
class InvoiceRepository:
def base_query(self, company_id=None):
if company_id is None:
company = CompanyService.get_current_company()
company_id = company.id if company else None
query = Invoice.query
if company_id:
query = query.filter(Invoice.company_id == company_id)
return query
def incoming_query(self, company_id=None):
query = self.base_query(company_id)
return query.filter(
Invoice.invoice_type != InvoiceType.SALE,
~Invoice.source.in_(['issued', 'nfz']),
)
def query_filtered(self, form_data, company_id=None):
query = self.incoming_query(company_id)
month = form_data.get('month')
year = form_data.get('year')
quick_filter = form_data.get('quick_filter')
min_amount = form_data.get('min_amount')
max_amount = form_data.get('max_amount')
if month:
query = query.filter(extract('month', Invoice.issue_date) == int(month))
if year:
query = query.filter(extract('year', Invoice.issue_date) == int(year))
if form_data.get('contractor'):
query = query.filter(Invoice.contractor_name.ilike(f"%{form_data['contractor']}%"))
if form_data.get('nip'):
query = query.filter(Invoice.contractor_nip.ilike(f"%{form_data['nip']}%"))
if form_data.get('invoice_type'):
query = query.filter(Invoice.invoice_type == InvoiceType(form_data['invoice_type']))
if form_data.get('status'):
query = query.filter(Invoice.status == InvoiceStatus(form_data['status']))
if min_amount:
query = query.filter(Invoice.gross_amount >= float(min_amount))
if max_amount:
query = query.filter(Invoice.gross_amount <= float(max_amount))
if form_data.get('search'):
term = f"%{form_data['search']}%"
query = query.filter(or_(Invoice.invoice_number.ilike(term), Invoice.ksef_number.ilike(term), Invoice.contractor_name.ilike(term), Invoice.contractor_nip.ilike(term)))
today = date.today()
if quick_filter == 'this_month':
query = query.filter(extract('month', Invoice.issue_date) == today.month, extract('year', Invoice.issue_date) == today.year)
elif quick_filter == 'previous_month':
prev = today.replace(day=1) - timedelta(days=1)
query = query.filter(extract('month', Invoice.issue_date) == prev.month, extract('year', Invoice.issue_date) == prev.year)
elif quick_filter == 'unread':
query = query.filter(Invoice.is_unread.is_(True))
elif quick_filter == 'error':
query = query.filter(Invoice.status == InvoiceStatus.ERROR)
elif quick_filter == 'to_send':
query = query.filter(Invoice.status.in_([InvoiceStatus.NEW, InvoiceStatus.READ]))
return query.order_by(Invoice.issue_date.desc(), Invoice.id.desc())
def get_by_ksef_number(self, ksef_number, company_id=None):
return self.base_query(company_id).filter_by(ksef_number=ksef_number).first()
def monthly_summary(self, company_id=None):
return self.base_query(company_id).with_entities(
extract('year', Invoice.issue_date).label('year'),
extract('month', Invoice.issue_date).label('month'),
func.count(Invoice.id).label('count'),
func.sum(Invoice.net_amount).label('net'),
func.sum(Invoice.vat_amount).label('vat'),
func.sum(Invoice.gross_amount).label('gross'),
).group_by('year', 'month').order_by(extract('year', Invoice.issue_date).desc(), extract('month', Invoice.issue_date).desc()).all()
def summary_query(self, company_id=None, *, period='month', search=None):
query = self.base_query(company_id)
if search:
like = f'%{search}%'
query = query.filter(or_(
Invoice.invoice_number.ilike(like),
Invoice.ksef_number.ilike(like),
Invoice.contractor_name.ilike(like),
Invoice.contractor_nip.ilike(like),
))
year_expr = extract('year', Invoice.issue_date)
month_expr = extract('month', Invoice.issue_date)
quarter_expr = ((month_expr - 1) / 3 + 1)
columns = [
year_expr.label('year'),
func.count(Invoice.id).label('count'),
func.sum(Invoice.net_amount).label('net'),
func.sum(Invoice.vat_amount).label('vat'),
func.sum(Invoice.gross_amount).label('gross'),
]
group_by = [year_expr]
order_by = [year_expr.desc()]
if period == 'month':
columns.append(month_expr.label('month'))
group_by.append(month_expr)
order_by.append(month_expr.desc())
elif period == 'quarter':
quarter_cast = cast(quarter_expr, Integer)
columns.append(quarter_cast.label('quarter'))
group_by.append(quarter_cast)
order_by.append(quarter_cast.desc())
return query.with_entities(*columns).group_by(*group_by).order_by(*order_by).all()