Esempio n. 1
0
    def __init__(self, store, date, printer):
        self.store = store
        self.start = date
        self.end = date

        if not printer:
            raise CATError(_(u"There must be a printer configured"))

        self.printer = printer
        self.driver = printer.get_fiscal_driver()
        self.cat = CATFile(self.printer)

        self._add_registers()
Esempio n. 2
0
    def __init__(self, store, date, printer):
        self.store = store
        self.start = date
        self.end = date

        if not printer:
            raise CATError(_(u"There must be a printer configured"))

        self.printer = printer
        self.driver = printer.get_fiscal_driver()
        self.cat = CATFile(self.printer)

        self._add_registers()
Esempio n. 3
0
class StoqlibCATGenerator(object):
    """This class is responsible for generating a CAT file from
    from the Stoq domain classes.
    """
    def __init__(self, store, date, printer):
        self.store = store
        self.start = date
        self.end = date

        if not printer:
            raise CATError(_(u"There must be a printer configured"))

        self.printer = printer
        self.driver = printer.get_fiscal_driver()
        self.cat = CATFile(self.printer)

        self._add_registers()

    def _get_file_name(self):
        # FFM12345.DMA
        # pylint: disable=W0402
        import string
        base = string.digits + string.uppercase
        # pylint: enable=W0402

        brand = BRAND_CODES[self.printer.brand]
        model = MODEL_CODES[(self.printer.brand, self.printer.model)]

        return "%s%s%s.%s%s%s" % (
            brand,
            model,
            self.printer.device_serial[-5:],
            base[self.end.day],
            base[self.end.month],
            base[self.end.year - 2000],
        )

    def write(self, dir):
        fullname = os.path.join(dir, self._get_file_name())
        self.cat.write(fullname)

    def _get_z_reductions(self):
        return self.store.find(
            FiscalDayHistory,
            And(
                Date(FiscalDayHistory.emission_date) == self.start,
                FiscalDayHistory.serial == self.printer.device_serial))

    def _get_sales(self, returned=False):
        # TODO: We need to add station_id to the sales table
        query = And(
            Date(Sale.confirm_date) == self.start,
            # Sale.station_id == self.printer.station_id
        )
        if returned:
            query = And(Date(Sale.return_date) == self.end, )

        return self.store.find(Sale, query)

    def _get_other_documents(self):
        return self.store.find(
            ECFDocumentHistory,
            And(
                Date(ECFDocumentHistory.emission_date) == self.start,
                ECFDocumentHistory.printer_id == self.printer.id))

    def _add_registers(self):
        appinfo = get_utility(IAppInfo)
        self.cat.add_software_house(company, appinfo.get('name'),
                                    appinfo.get('version'))

        self._add_ecf_identification()
        self._add_z_reduction_information()
        self._add_fiscal_coupon_information()
        self._add_other_documents()

    def _add_ecf_identification(self):
        # XXX: We need to verity that all items are related to the current printer.
        items = list(self._get_z_reductions())

        initial_crz = 0
        final_crz = 0
        total = 0
        if len(items):
            initial_crz = items[0].crz
            final_crz = items[-1].crz
            total = items[-1].total

        branch = get_current_branch(self.store)
        company = branch.person.company
        self.cat.add_ecf_identification(self.driver, company, initial_crz,
                                        final_crz, self.start, self.end)

        self.cat.add_ecf_user_identification(company, total)

    def _add_z_reduction_information(self):
        z_reductions = list(self._get_z_reductions())

        # First we add z_reduction information
        for item in z_reductions:
            self.cat.add_z_reduction(item)

        # Then we add the details
        for item in z_reductions:
            for i, tax in enumerate(item.taxes):
                self.cat.add_z_reduction_details(item, tax, i + 1)

    def _add_fiscal_coupon_information(self):
        sales = list(self._get_sales())
        iss_tax = sysparam.get_decimal('ISS_TAX') * 100

        for sale in sales:
            client = sale.client
            history = self.store.find(FiscalSaleHistory, sale=sale)

            # We should have exactly one row with the paulista invoice details
            if len(list(history)) != 1:
                continue

            self.cat.add_fiscal_coupon(sale, client, history[0])

            for i, item in enumerate(sale.get_items()):
                self.cat.add_fiscal_coupon_details(sale, client, history[0],
                                                   item, iss_tax, i + 1)

            # Ignore returned sales here, they will be handled later
            if sale.return_date:
                continue

            for payment in sale.payments:
                # Pagamento de entrada para devoluções. Nós não devemos incluir
                # esse pagamento, pois a empresa deve preencher uma nota de
                # entrada para pedir a devolução do imposto.
                if payment.is_inpayment():
                    continue
                self.cat.add_payment_method(sale, history[0], payment)

        # Essas vendas são as que foram devolvidas *imediatamente após* terem
        # sido emitida. Ou seja, houve o cancelamento da mesma na ECF, então os
        # pagamentos de estorno devem ser adicionados. ao cat
        returned_sales = list(self._get_sales(returned=True))
        for sale in returned_sales:
            history = self.store.find(FiscalSaleHistory, sale=sale)
            # We should have exactly one row with the paulista invoice details
            if len(list(history)) != 1:
                continue

            returned_sales = list(self.store.find(ReturnedSale, sale=sale))
            # We should only handle sales cancelled right after they were made,
            # and they have only one returned_sale object related
            if len(returned_sales) != 1:
                continue

            # Sales cancelled right after being made dont have an invoice number
            if returned_sales[0].invoice.invoice_number is not None:
                continue

            for payment in sale.payments:
                if payment.is_outpayment():
                    continue

                self.cat.add_payment_method(sale, history[0], payment,
                                            returned_sales[0])

    def _add_other_documents(self):
        docs = list(self._get_other_documents())

        for doc in docs:
            self.cat.add_other_document(doc)
Esempio n. 4
0
class StoqlibCATGenerator(object):
    """This class is responsible for generating a CAT file from
    from the Stoq domain classes.
    """
    def __init__(self, store, date, printer):
        self.store = store
        self.start = date
        self.end = date

        if not printer:
            raise CATError(_(u"There must be a printer configured"))

        self.printer = printer
        self.driver = printer.get_fiscal_driver()
        self.cat = CATFile(self.printer)

        self._add_registers()

    def _get_file_name(self):
        # FFM12345.DMA
        # pylint: disable=W0402
        import string
        base = string.digits + string.uppercase
        # pylint: enable=W0402

        brand = BRAND_CODES[self.printer.brand]
        model = MODEL_CODES[(self.printer.brand, self.printer.model)]

        return "%s%s%s.%s%s%s" % (brand,
                                  model,
                                  self.printer.device_serial[-5:],
                                  base[self.end.day],
                                  base[self.end.month],
                                  base[self.end.year - 2000],
                                  )

    def write(self, dir):
        fullname = os.path.join(dir, self._get_file_name())
        self.cat.write(fullname)

    def _get_z_reductions(self):
        return self.store.find(FiscalDayHistory,
                               And(Date(FiscalDayHistory.emission_date) == self.start,
                                   FiscalDayHistory.serial == self.printer.device_serial))

    def _get_sales(self, returned=False):
        # TODO: We need to add station_id to the sales table
        query = And(Date(Sale.confirm_date) == self.start,
                    # Sale.station_id == self.printer.station_id
                    )
        if returned:
            query = And(Date(Sale.return_date) == self.end, )

        return self.store.find(Sale, query)

    def _get_other_documents(self):
        return self.store.find(ECFDocumentHistory,
                               And(Date(ECFDocumentHistory.emission_date) == self.start,
                                   ECFDocumentHistory.printer_id == self.printer.id))

    def _add_registers(self):
        appinfo = get_utility(IAppInfo)
        self.cat.add_software_house(async, appinfo.get('name'),
                                    appinfo.get('version'))

        self._add_ecf_identification()
        self._add_z_reduction_information()
        self._add_fiscal_coupon_information()
        self._add_other_documents()

    def _add_ecf_identification(self):
        # XXX: We need to verity that all items are related to the current printer.
        items = list(self._get_z_reductions())

        initial_crz = 0
        final_crz = 0
        total = 0
        if len(items):
            initial_crz = items[0].crz
            final_crz = items[-1].crz
            total = items[-1].total

        branch = get_current_branch(self.store)
        company = branch.person.company
        self.cat.add_ecf_identification(self.driver, company, initial_crz,
                                        final_crz, self.start, self.end)

        self.cat.add_ecf_user_identification(company, total)

    def _add_z_reduction_information(self):
        z_reductions = list(self._get_z_reductions())

        # First we add z_reduction information
        for item in z_reductions:
            self.cat.add_z_reduction(item)

        # Then we add the details
        for item in z_reductions:
            for i, tax in enumerate(item.taxes):
                self.cat.add_z_reduction_details(item, tax, i + 1)

    def _add_fiscal_coupon_information(self):
        sales = list(self._get_sales())
        iss_tax = sysparam(self.store).ISS_TAX * 100

        for sale in sales:
            client = sale.client
            history = self.store.find(FiscalSaleHistory, sale=sale)

            # We should have exactly one row with the paulista invoice details
            if len(list(history)) != 1:
                continue

            self.cat.add_fiscal_coupon(sale, client, history[0])

            for i, item in enumerate(sale.get_items()):
                self.cat.add_fiscal_coupon_details(sale, client, history[0],
                                                   item, iss_tax, i + 1)

            # Ignore returned sales here, they will be handled later
            if sale.return_date:
                continue

            for payment in sale.payments:
                # Pagamento de entrada para devoluções. Nós não devemos incluir
                # esse pagamento, pois a empresa deve preencher uma nota de
                # entrada para pedir a devolução do imposto.
                if payment.is_inpayment():
                    continue
                self.cat.add_payment_method(sale, history[0], payment)

        # Essas vendas são as que foram devolvidas *imediatamente após* terem
        # sido emitida. Ou seja, houve o cancelamento da mesma na ECF, então os
        # pagamentos de estorno devem ser adicionados. ao cat
        returned_sales = list(self._get_sales(returned=True))
        for sale in returned_sales:
            history = self.store.find(FiscalSaleHistory, sale=sale)
            # We should have exactly one row with the paulista invoice details
            if len(list(history)) != 1:
                continue

            returned_sales = list(self.store.find(ReturnedSale, sale=sale))
            # We should only handle sales cancelled right after they were made,
            # and they have only one returned_sale object related
            if len(returned_sales) != 1:
                continue

            # Sales cancelled right after being made dont have an invoice number
            if returned_sales[0].invoice_number is not None:
                continue

            for payment in sale.payments:
                if payment.is_outpayment():
                    continue

                self.cat.add_payment_method(sale, history[0], payment,
                                            returned_sales[0])

    def _add_other_documents(self):
        docs = list(self._get_other_documents())

        for doc in docs:
            self.cat.add_other_document(doc)
Esempio n. 5
0
    def test_complete(self):
        station = self.create_station()
        today = datetime.date(2007, 1, 1)
        reduction_date = datetime.datetime(2007, 1, 1, 23, 59)
        day = FiscalDayHistory(store=self.store,
                               emission_date=today,
                               station=station,
                               serial=u'serial',
                               serial_id=1,
                               coupon_start=1,
                               coupon_end=23,
                               crz=18,
                               cro=25,
                               period_total=Decimal("456.00"),
                               total=Decimal("123141.00"),
                               reduction_date=reduction_date)
        for code, value, type in [(u'2500', Decimal("123.00"), u'ICMS'),
                                  (u'F', Decimal("789.00"), u'ICMS')]:
            FiscalDayTax(fiscal_day_history=day, code=code,
                         value=value, type=type,
                         store=self.store)

        printer = ECFPrinter(
            store=self.store,
            model=u'FS345',
            brand=u'daruma',
            device_name=u'test',
            device_serial=u'serial',
            baudrate=9600,
            station=station,
            user_number=1,
            register_date=today,
            register_cro=1,
        )

        f = CATFile(printer)
        f.software_version = '6.6.6'  # kiko sends <3

        appinfo = get_utility(IAppInfo)
        f.add_software_house(company, appinfo.get('name'),
                             appinfo.get('version'))
        # Cant call add_ecf_identification, since it depends on a
        # conected printer
        # f.add_ecf_identification()

        for item in self.store.find(FiscalDayHistory):
            f.add_z_reduction(item)
            for i, tax in enumerate(item.taxes):
                f.add_z_reduction_details(item, tax, i + 1)

        sale = self.create_sale()
        sale.client = self.create_client()
        sale.confirm_date = today
        sellable = self.add_product(sale, price=100)
        sellable.code = u'09999'

        self.add_payments(sale)
        history = FiscalSaleHistory(store=self.store,
                                    sale=sale)

        f.add_fiscal_coupon(sale, sale.client, history)
        for i, item in enumerate(sale.get_items()):
            f.add_fiscal_coupon_details(sale, sale.client, history,
                                        item, 800, i + 1)

        for payment in sale.payments:
            f.add_payment_method(sale, history, payment)

        diff = compare_files(f, 'cat52')
        self.assertFalse(diff, '%s\n%s' % ("Files differ, output:", diff))