def _create_payment(self): group = PaymentGroup() group.payer = self.client.person method = PaymentMethod.get_by_name(self.store, u'credit') branch = api.get_current_branch(self.store) if self.model.value < 0: payment_type = Payment.TYPE_IN else: payment_type = Payment.TYPE_OUT # Set status to PENDING now, to avoid calling set_pending on # on_confirm for payments that shoud not have its status changed. payment = Payment(open_date=localtoday(), branch=branch, status=Payment.STATUS_PENDING, description=self.model.description, value=abs(self.model.value), base_value=abs(self.model.value), due_date=localtoday(), method=method, group=group, till=None, category=None, payment_type=payment_type, bill_received=False) payment.pay() return payment
def _create_freight_payment(self): store = self.store money_method = PaymentMethod.get_by_name(store, u'money') # If we have a transporter, the freight payment will be for him # (and in another payment group). if self.transporter is not None: group = PaymentGroup(store=store) group.recipient = self.transporter.person else: group = self.purchase.group description = _(u'Freight for purchase %s') % ( self.purchase.get_order_number_str(), ) payment = money_method.create_outpayment( group, self.branch, self.freight_total, due_date=datetime.datetime.today(), description=description) payment.set_pending() return payment
def _create_freight_payment(self): store = self.store money_method = PaymentMethod.get_by_name(store, u'money') # If we have a transporter, the freight payment will be for him # (and in another payment group). if self.transporter is not None: group = PaymentGroup(store=store) group.recipient = self.transporter.person else: group = self.purchase.group description = _(u'Freight for purchase %s') % ( self.purchase.identifier, ) payment = money_method.create_payment( Payment.TYPE_OUT, group, self.branch, self.freight_total, due_date=localnow(), description=description) payment.set_pending() return payment
def _create_receiving_invoice(self): # We only let the user get this far if the receivings selected are for the # same branch and supplier supplier = self.receivings[0].purchase.supplier branch_id = self.receivings[0].branch_id # If the receiving is for another branch, we need a temporary identifier temporary_identifier = None if (api.sysparam.get_bool('SYNCHRONIZED_MODE') and api.get_current_branch(self.store).id != branch_id): temporary_identifier = ReceivingInvoice.get_temporary_identifier(self.store) group = PaymentGroup(store=self.store, recipient=supplier.person) self.wizard.model = self.model = ReceivingInvoice( identifier=temporary_identifier, supplier=supplier, group=group, branch_id=branch_id, store=self.store, responsible=api.get_current_user(self.store)) for row in self.receivings: self.model.add_receiving(row.order)
def create_freight_payment(self, group=None): store = self.store money_method = PaymentMethod.get_by_name(store, u'money') # If we have a transporter, the freight payment will be for him if not group: if self.transporter: recipient = self.transporter.person else: recipient = self.supplier.person group = PaymentGroup(store=store, recipient=recipient) description = _(u'Freight for receiving %s') % (self.identifier, ) payment = money_method.create_payment(Payment.TYPE_OUT, group, self.branch, self.freight_total, due_date=localnow(), description=description) payment.set_pending() return payment
def create_model(self, store): group = PaymentGroup() money = PaymentMethod.get_by_name(store, u'money') branch = api.get_current_branch(store) # Set status to PENDING now, to avoid calling set_pending on # on_confirm for payments that shoud not have its status changed. return Payment(store=store, open_date=localtoday().date(), branch=branch, station=api.get_current_station(store), status=Payment.STATUS_PENDING, description=u'', value=currency(0), base_value=currency(0), due_date=None, method=money, group=group, category=None, payment_type=self.payment_type, bill_received=False)
def finish(self): for loan in self.models: for item in loan.loaned_items: original = self.original_items[item] sale_quantity = item.sale_quantity - original.sale_quantity if sale_quantity > 0: self._sold_items.append( (item.sellable, sale_quantity, item.price)) if self._create_sale and self._sold_items: user = api.get_current_user(self.store) sale = Sale( store=self.store, # Even if there is more than one loan, they are always from the # same (client, branch) branch=self.models[0].branch, client=self.models[0].client, salesperson=user.person.salesperson, group=PaymentGroup(store=self.store), coupon_id=None) for sellable, quantity, price in self._sold_items: sale.add_sellable(sellable, quantity, price, # Quantity was already decreased on loan quantity_decreased=quantity) sale.order() info(_("Close loan details..."), _("A sale was created from loan items. You can confirm " "that sale in the Till application later.")) else: sale = None for model in self.models: model.sync_stock() if model.can_close(): model.close() self.retval = self.models self.close() CloseLoanWizardFinishEvent.emit(self.models, sale, self)
def _get_purchase_from_quote(self, quote, store): quote_purchase = quote.purchase real_order = quote_purchase.clone() has_selected_items = False # add selected items for quoted_item in self.quoted_items: order = store.fetch(quoted_item.order) if order is quote_purchase and quoted_item.selected: purchase_item = store.fetch(quoted_item.item).clone() purchase_item.order = real_order has_selected_items = True # override some cloned data real_order.group = PaymentGroup(store=store) real_order.open_date = localtoday().date() real_order.quote_deadline = None real_order.status = PurchaseOrder.ORDER_PENDING if has_selected_items: return real_order else: store.remove(real_order)
def _create_freight_payment(self): store = self.store money_method = PaymentMethod.get_by_name(store, u'money') # If we have a transporter, the freight payment will be for him # (and in another payment group). purchases = list(self.purchase_orders) if len(purchases) == 1 and self.transporter is None: group = purchases[0].group else: if self.transporter: recipient = self.transporter.person else: recipient = self.supplier.person group = PaymentGroup(store=store, recipient=recipient) description = _(u'Freight for receiving %s') % (self.identifier, ) payment = money_method.create_payment(Payment.TYPE_OUT, group, self.branch, self.freight_total, due_date=localnow(), description=description) payment.set_pending() return payment
def process_one(self, data, fields, store): person = store.find(Person, name=data.supplier_name).one() if person is None or person.supplier is None: raise ValueError(u"%s is not a valid supplier" % (data.supplier_name, )) supplier = person.supplier person = store.find(Person, name=data.transporter_name).one() if person is None or person.transporter is None: raise ValueError(u"%s is not a valid transporter" % (data.transporter_name, )) transporter = person.transporter person = store.find(Person, name=data.branch_name).one() if person is None or person.branch is None: raise ValueError(u"%s is not a valid branch" % (data.branch_name, )) branch = person.branch login_user = store.find(LoginUser, username=u'admin').one() group = PaymentGroup(store=store) purchase = PurchaseOrder(store=store, status=PurchaseOrder.ORDER_PENDING, open_date=self.parse_date(data.due_date), supplier=supplier, transporter=transporter, group=group, responsible=get_current_user(store), branch=branch) for sellable in self.parse_multi(Sellable, data.sellable_list, store): if not sellable.product: continue PurchaseItem(store=store, quantity=int(data.quantity), base_cost=sellable.cost, sellable=sellable, order=purchase) method = PaymentMethod.get_by_name(store, data.payment_method) method.create_payment(Payment.TYPE_OUT, purchase.group, branch, purchase.purchase_total, self.parse_date(data.due_date)) purchase.confirm() for payment in purchase.payments: payment.open_date = purchase.open_date receiving_order = ReceivingOrder(responsible=login_user, supplier=supplier, invoice_number=int(data.invoice), transporter=transporter, branch=branch, store=store) receiving_order.add_purchase(purchase) for purchase_item in purchase.get_items(): ReceivingOrderItem(store=store, cost=purchase_item.sellable.cost, sellable=purchase_item.sellable, quantity=int(data.quantity), purchase_item=purchase_item, receiving_order=receiving_order) receiving_order.confirm()
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
def _create_payment_group(self): return PaymentGroup(store=self.store, recipient=self.nfe_supplier.supplier.person, payer=self.branch.person)
def create_payment_group(self): from stoqlib.domain.payment.group import PaymentGroup return PaymentGroup(store=self.store)