Código fuente para impar.datecontext

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# "THE WISKEY-WARE LICENSE":
# <jbc.develop@gmail.com> and <nluczywo@gmail.com> wrote this file.
# As long as you retain this notice you can do whatever you want with this stuff.
# If we meet some day, and you think this stuff is worth it, you can buy me a
# WISKEY in return Juan BC and Nadia AL

#===============================================================================
# DOCS
#===============================================================================

"""Manejador de contexto de fechas para los impuestos"""

#===============================================================================
# IMPORTS
#===============================================================================

import os
import datetime
import importlib
import re


#===============================================================================
# CONSTANTS
#===============================================================================

PATH = os.path.abspath(os.path.dirname(__file__))

IMPS_PATH = os.path.join(PATH, "_impuestos")

DATE_FORMAT = "%Y%m%d"

TAXES = {}
TAXES_MIN_DATE = {}
for impuesto in os.listdir(IMPS_PATH):
    imp_path = os.path.join(IMPS_PATH, impuesto)
    if os.path.isdir(imp_path) and not impuesto.startswith("_"):
        modnames = []
        rx_imp = re.compile(
            "^{}_[0-9]{{4}}[0-9]{{2}}[0-9]{{2}}[.]py$".format(impuesto),
            re.UNICODE
        )
        for fname in os.listdir(imp_path):
            if rx_imp.match(fname):
                date = datetime.datetime.strptime(
                    fname.rsplit("_", 1)[-1][:-3], DATE_FORMAT
                ).date()
                modname = "impar._impuestos.{}.{}".format(
                    impuesto, fname.rsplit(".", 1)[0]
                )
                modnames.append((date, modname))
        modnames.sort(reverse=True)
        if modnames:
            TAXES[impuesto] = tuple(modnames)
            TAXES_MIN_DATE[impuesto] = modnames[-1][0]


#===============================================================================
# ERRORS
#===============================================================================

[documentos]class NotSuitableTax(ImportError): """Si no existe un impuesto de fecha menor o igual a del contexto""" pass
[documentos]class TaxNotExists(ImportError): """El impuesto no existe""" pass #=============================================================================== # CLASS #===============================================================================
[documentos]class DateContext(object): """Define un contexto de calculo para impuestos. En la practica asume todas las legislaciones a la fecha dada en el contexto para cada impuesto Si usted quiere calcular el impuestoA a con las legislaciones vigentes al dia 31 de octubre del 2012 deberia ejecutar el codigo de la siguiente manera >>> import datetime, impar >>> ctx = impar.DateContext(datetime(2012, 10, 31)) >>> impuestoA = ctx.get("impuestoA") >>> impuestoA.calcular(...) :param date: Fecha del contexto (hasta que fehca maxima se toman en cuenta las legislaciones para los impuestos). Si el valor es ``None`` se toma la fecha actual. :type date: datetime.date """ def __init__(self, date=None): """Crea una nueva instancia de contexto""" self._date = parse_date(date) self._strdate = self._date.strftime(DATE_FORMAT) self._valid_taxes = valid_taxes(self._date) self._buff = {} def __repr__(self): """obj.__repr__() <==> repr(obj)""" return "<DateContext '{}' at {}>".format(self._date, hex(id(self))) def _load(self, tax): if tax not in self._buff: if tax not in TAXES: msg = "impuesto '{}' inexistente" raise TaxNotExists(msg.format(tax)) elif tax not in self._valid_taxes: msg = "No hay una implementacion valida del impuesto {} para este contexto" raise NotSuitableTax(msg.format(tax)) for date, modname in TAXES[tax]: if date <= self.date: self._buff[tax] = date, importlib.import_module(modname) break
[documentos] def get(self, impuesto): """Retorna una implementación del impuesto dada la fecha del contexto :param impuesto: nombre del impuesto :type impuesto: str """ self._load(impuesto) return self._buff[impuesto][1]
[documentos] def date_of(self, impuesto): """Retorna la fecha exacta de la implementación del impuesto utilizada por este contexto :param impuesto: nombre del impuesto :type impuesto: str """ self._load(impuesto) return self._buff[impuesto][0]
@property
[documentos] def date(self): """Fecha del contexto""" return self._date
@property
[documentos] def valid_taxes(self): """Impuestos validos para este contexto""" return self._valid_taxes #~ #=============================================================================== #~ # FUNCTIONS #~ #===============================================================================
[documentos]def parse_date(date): """Convierte varios tipos de objetos a instancias de datetime.date Todas estas funciones son equivalentes: >>> # asumiendo que hoy es 25 de diciembre del 2013 >>> parse_date() >>> parse_date(datetime.datetime.now()) >>> parse_date(datetime.datetime.now().date()) >>> parse_date(datetime.datetime(2013,12,25)) >>> parse_date(datetime.date(2013,12,25)) >>> parse_date("20131225") >>> parse_date("2013-12-25") >>> parse_date("2013_12_25") >>> parse_date("2013_12-25") >>> parse_date("2013-12_25") >>> parse_date("2013/12/25") >>> parse_date("2013/12-25") >>> parse_date("2013-12/25") >>> parse_date("2013/12_25") >>> parse_date("2013_12/25") >>> parse_date((2013, 12, 25)) """ if isinstance(date, datetime.date): return date elif date is None: return datetime.datetime.now().date() elif isinstance(date, basestring): date = date.replace("-", "").replace("_", "").replace("/", "") return datetime.datetime.strptime(date, DATE_FORMAT).date() elif isinstance(date, datetime.datetime): return date.date() return datetime.date(*date)
[documentos]def valid_taxes(date=None): """Retorna una tupla de todos los impuestos validos para una fecha dada, o todos si la fecha es None""" valids = [] if date: for tax, mindate in TAXES_MIN_DATE.items(): if mindate <= date: valids.append(tax) else: valids = TAXES_MIN_DATE.keys() return frozenset(valids)
[documentos]def same_implementation(date0, date1): """Retorna un set con todos los impuestos que poseen la misma implentacion en ambas fechas """ ctx0 = DateContext(date0) ctx1 = DateContext(date0) return frozenset( tax for tax in ctx0.valid_taxes.intersection(ctx1.valid_taxes) if ctx0.date_of(tax) == ctx1.date_of(tax) ) #=============================================================================== # MAIN #===============================================================================
if __name__ == "__main__": print(__doc__)
Read the Docs v: latest
Versions
latest
Downloads
PDF
HTML
Epub
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.