"""Logic for Ledger Accounting Run VAT.""" from abacus_common_logic.connectors.database import db from marshmallow import ValidationError from owsresponse import response from ledger.constants.constants import ( DEFAULT_PAGE_LIMIT, DEFAULT_PAGE_OFFSET, ERROR_INVALID_LIMIT_OFFSET, VAT_CATEGORIES_OLD, ) from ledger.constants.error import ( ERROR_COUNTRY_CODE_REQUIRED, ERROR_UNKNOWN_CURRENCY, INVALID_VAT_CATEGORY, ) from ledger.models.ledger_accounting_run_vat import LedgerAccountingRunVat from ledger.schemas.ledger_accounting_run_vat import ( LedgerAccountingRunVatDetailSchema, LedgerAccountingRunVatOverviewSchema, LedgerAccountingRunVatSchema, ) from ledger.utils.country import validate_country_code from ledger.utils.currency import currency_exists from ledger.utils.format_error import validation_error def bulk_create(request): """Bulk create Ledger Accounting Run VAT logic.""" new_ledger_accounting_run_vats = list() try: for record in request: validate_record(record) new_ledger_accounting_run_vat = LedgerAccountingRunVat.build(**record) new_ledger_accounting_run_vats.append(new_ledger_accounting_run_vat) except ValidationError as e: return validation_error(str(e)) db.session.commit() return response.Response( message={ 'items': LedgerAccountingRunVatDetailSchema().dump( new_ledger_accounting_run_vats, many=True ), 'total_count': len(new_ledger_accounting_run_vats), }, status=201, ) def validate_record(record): """Validate incoming Ledger Accounting Run VAT record.""" validate_country_code(record['country_of_tax_residence']) if not currency_exists(record.get('currency_code')): raise ValidationError( ERROR_UNKNOWN_CURRENCY.format(code=record.get('currency_code')) ) def get_ledger_accounting_run_vat_overview(accounting_period_id): """Get count of contracts by VAT category for a specific accounting_period.""" items = LedgerAccountingRunVat.get_ledger_accounting_run_vat_overview( accounting_period_id ) return response.Response( message=LedgerAccountingRunVatOverviewSchema().dump(items, many=True), status=200, ) def get_ledger_vat_list(accounting_period_id, vat_category, request_params): """Get list of ledger run vat for an accounting period by vat category and country code. Args: accounting_period_id (int): id of accounting period vat_category (string): category of vat request_params (dict): dict of query string passed to the url request_params could be: country_code: Optional[str] for vat_exempt category limit: Optional[int] offset: Optional[int] """ try: params_or_error = _validate_request_params(vat_category, request_params) except Exception as e: return validation_error(str(e)) result = LedgerAccountingRunVat.get_ledger_vat_list( accounting_period_id, **params_or_error ) count = LedgerAccountingRunVat.get_ledger_vat_list_count( accounting_period_id, vat_category, params_or_error['country_code'] ) return response.Response( message={ 'items': LedgerAccountingRunVatSchema().dump(result, many=True), 'total_count': count, }, status=200, ) def _validate_request_params(vat_category, request_params): """Format and validate request parameters.""" limit = DEFAULT_PAGE_LIMIT offset = DEFAULT_PAGE_OFFSET country_code = request_params.get('country_code', None) try: limit = int(request_params.get('limit', limit)) offset = int(request_params.get('offset', offset)) except ValueError: raise Exception(ERROR_INVALID_LIMIT_OFFSET) if vat_category not in VAT_CATEGORIES_OLD: raise Exception( INVALID_VAT_CATEGORY.format( VAT_CATEGORIES_OLD=(', '.join(VAT_CATEGORIES_OLD)) ) ) if vat_category == VAT_CATEGORIES_OLD.VAT_APPLIED: if country_code is None: raise Exception(ERROR_COUNTRY_CODE_REQUIRED) validate_country_code(country_code) return { 'vat_category': vat_category, 'country_code': country_code, 'limit': max(limit, 1), 'offset': max(offset, 0), }