def _get_by_doc(self, store, data, doc): # Extra precaution in case we ever send the cpf already formatted document = format_cpf(raw_document(doc)) person = Person.get_by_document(store, document) if not person or not person.client: return data return self._dump_client(person.client)
def next_step(self): if self.individual_check.get_active(): role_type = Person.ROLE_INDIVIDUAL else: role_type = Person.ROLE_COMPANY # If someone wants to register with an empty document if self.person_document.is_empty(): return RoleEditorStep(self.wizard, self.store, self, role_type) person = Person.get_by_document(self.store, self.model.person_document) return RoleEditorStep(self.wizard, self.store, self, role_type, person, document=self.model.person_document)
def next_step(self): if self.individual_check.get_active(): role_type = Person.ROLE_INDIVIDUAL else: role_type = Person.ROLE_COMPANY # If someone wants to register with an empty document if self.person_document.is_empty(): return RoleEditorStep(self.wizard, self.store, self, role_type, description=self._description) person = Person.get_by_document(self.store, self.model.person_document) return RoleEditorStep(self.wizard, self.store, self, role_type, person, document=self.model.person_document)
def _get_by_doc(self, store, data, doc): # Extra precaution in case we ever send the cpf already formatted document = format_cpf(raw_document(doc)) person = Person.get_by_document(store, document) if person and person.client: data = self._dump_client(person.client) # Plugins that listen to this signal will return extra fields # to be added to the response responses = signal('CheckRewardsPermissionsEvent').send(doc) for response in responses: data.update(response[1]) return data
def _update_sale_client(self): """Update the sale client based on the informed document If the sale does not have a client yet, and the current_document (informed by the ecf plugin) is set, and a person with the given document exists, that client will be associated with this sale. """ if self.model.client or not self.wizard._current_document: return person = Person.get_by_document(self.store, str(self.wizard._current_document)) if not person: return if person.client: self.model.client = person.client else: self.model.client = Client(store=self.store, person=person)
def _find_branch(self, branch_id=None): cnpj = self._format_cnpj(self._get_text('/infNFe/dest/CNPJ', self.root)) if branch_id: branch = self.store.get(Branch, branch_id) if cnpj != branch.person.company.cnpj: raise NFeDifferentCNPJ(cnpj) try: person = Person.get_by_document(self.store, cnpj) except NotOneError: # Found multiple branchs with the same CNPJ, so we get it by id person = self.store.get(Branch, branch_id).person if branch_id else None if person is None: return None, cnpj provide_utility(ICurrentBranch, person.branch, replace=True) return person.branch, cnpj
def post(self, store): # FIXME: Check branch state and force fail if no override for that product is present. self.ensure_printer() data = request.get_json() client_id = data.get('client_id') products = data['products'] payments = data['payments'] client_category_id = data.get('price_table') document = raw_document(data.get('client_document', '') or '') if document: document = format_document(document) if client_id: client = store.get(Client, client_id) elif document: person = Person.get_by_document(store, document) client = person and person.client else: client = None # Create the sale branch = api.get_current_branch(store) group = PaymentGroup(store=store) user = api.get_current_user(store) sale = Sale( store=store, branch=branch, salesperson=user.person.sales_person, client=client, client_category_id=client_category_id, group=group, open_date=localnow(), coupon_id=None, ) # Add products for p in products: sellable = store.get(Sellable, p['id']) item = sale.add_sellable(sellable, price=currency(p['price']), quantity=decimal.Decimal(p['quantity'])) # XXX: bdil has requested that when there is a special discount, the discount does # not appear on the coupon. Instead, the item wil be sold using the discount price # as the base price. Maybe this should be a parameter somewhere item.base_price = item.price # Add payments sale_total = sale.get_total_sale_amount() money_payment = None payments_total = 0 for p in payments: method_name = p['method'] tef_data = p.get('tef_data', {}) if method_name == 'tef': p['provider'] = tef_data['card_name'] method_name = 'card' method = PaymentMethod.get_by_name(store, method_name) installments = p.get('installments', 1) or 1 due_dates = list(create_date_interval( INTERVALTYPE_MONTH, interval=1, start_date=localnow(), count=installments)) payment_value = currency(p['value']) payments_total += payment_value p_list = method.create_payments( Payment.TYPE_IN, group, branch, payment_value, due_dates) if method.method_name == 'money': # FIXME Frontend should not allow more than one money payment. this can be changed # once https://gitlab.com/stoqtech/private/bdil/issues/75 is fixed? if not money_payment or payment_value > money_payment.value: money_payment = p_list[0] elif method.method_name == 'card': for payment in p_list: card_data = method.operation.get_card_data_by_payment(payment) card_type = p['mode'] # Stoq does not have the voucher comcept, so register it as a debit card. if card_type == 'voucher': card_type = 'debit' device = self._get_card_device(store, 'TEF') provider = self._get_provider(store, p['provider']) if tef_data: card_data.nsu = tef_data['aut_loc_ref'] card_data.auth = tef_data['aut_ext_ref'] card_data.update_card_data(device, provider, card_type, installments) card_data.te.metadata = tef_data # If payments total exceed sale total, we must adjust money payment so that the change is # correctly calculated.. if payments_total > sale_total and money_payment: money_payment.value -= (payments_total - sale_total) assert money_payment.value >= 0 # Confirm the sale group.confirm() sale.order() till = Till.get_last(store) sale.confirm(till) # Fiscal plugins will connect to this event and "do their job" # It's their responsibility to raise an exception in case of # any error, which will then trigger the abort bellow # FIXME: Catch printing errors here and send message to the user. SaleConfirmedRemoteEvent.emit(sale, document) # This will make sure we update any stock or price changes products may # have between sales return True