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()
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)
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)
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))