def cart_session_to_invoice(request, date=None): """ Create an invoice from cart session data If date is none, its a proforma invoice """ if date: proforma = False number = Invoice.next_number() else: date = now() proforma = True number = 0 invoice = Invoice(date=date, proforma=proforma, number=number) invoice.buyer = cart_get_buyer(request) invoice.address = invoice.buyer.main_address invoice.save() total = Decimal(0) for item in cart_items(request): total += item.agreed_price item.sale_price = item.agreed_price item.state = Item.State.SOLD item.invoice = invoice item.archive = True item.save() for charge in cart_charges(request): total += charge.amount charge.invoice = invoice charge.save() invoice.total = total invoice.save() cart_clear(request) return invoice
def report_on_site_payments(): one_month_ago = datetime.datetime.today() - relativedelta(months=1) min_date = int(time.mktime(one_month_ago.timetuple())) invoices = Invoice.all().filter('payment_type', Invoice.PAYMENT_ON_SITE).filter( 'date >=', min_date) charges = Charge.get((i.charge_key for i in invoices)) customers = Customer.get((i.order_key.parent() for i in invoices)) l = [ '[%(date_str)s][%(customer)s][%(manager)s][%(amount).02f][%(charge_number)s]' % dict(customer=c.name, manager=i.operator, amount=i.amount / 100.0, date=i.date, date_str=time.ctime(i.date), charge_number=charge.charge_number) for (i, charge, c) in sorted(zip(invoices, charges, customers), key=lambda t: t[0].date) ] body = "\n".join(l) or u"There were no on site payments for the last month" logging.info(body) server_settings = get_server_settings() solution_server_settings = get_solution_server_settings() subject = u'On site payments for the last month' send_mail(server_settings.dashboardEmail, solution_server_settings.shop_payment_admin_emails, subject, body)
def verify(request): # GET request containing pass code as a param url_key = request.GET.get('key') pass_key_object = PassKey.objects.get(url_key=url_key) user_id = pass_key_object.user_id # Do a check if there are any previously generated pass_key_objects associated with this user previous_pass_keys = PassKey.objects.exclude( url_key=pass_key_object.url_key).filter(user_id=user_id) # If there are any, delete them one by one if len(previous_pass_keys) > 0: for i in range(0, len(previous_pass_keys)): previous_pass_keys[i].delete() # Query for the user's verified field on userAdditionalInfo table user_additional_info = UserAdditionalInfo.objects.get( user_id=pass_key_object.user_id) # Change the verified status to True and save user_additional_info.verified = 1 user_additional_info.save() # get rid of url_key_object pass_key_object.delete() # Creating cart only after the user has been verified # Query for the id of the just created user's id number new_user = User.objects.filter(id=pass_key_object.user_id)[0] new_user_id = new_user.id new_user_registered_time = new_user.date_joined new_cart_status = InvoiceStatus.objects.get(id=1) # Use that id number to create new invoice(cart) new_cart = Invoice(user=new_user, status=new_cart_status, date=new_user_registered_time) new_cart.save() return HttpResponse('User\'s email has been verified', content_type='text/plain')
def _get_invoice_number(charge): invoices = list(Invoice.all(keys_only=True).ancestor(charge)) if len(invoices) == 1: return invoices[0].name() elif len(invoices) == 0: return "" else: from shop.bizz import PaymentFailedException raise PaymentFailedException("Found multiple invoices for charge %r!" % charge.key())
def _job(): order_numbers = list(OrderNumber.all()) charge_numbers = list(ChargeNumber.all()) invoice_numbers = list(InvoiceNumber.all()) # Change parent from some OrderNumbers from RegioMangerTeam to LegalEntity. # Increase last_number for that legal entity when the parent was a team. to_delete = list() for ordernumber in order_numbers: if ordernumber.parent_key().kind() == RegioManagerTeam.kind(): # Delete OrderNumber with parent RegioManagerTeam logging.warn( "Deleting OrderNumber Year %s Original last number: %s" % (ordernumber.key().name(), ordernumber.last_number)) to_delete.append(ordernumber) for chargenumber in charge_numbers: if chargenumber.parent_key().kind() == RegioManagerTeam.kind(): logging.warn( "Deleting ChargeNumber Year %s Original last number: %s" % (chargenumber.key().name(), chargenumber.last_number)) to_delete.append(chargenumber) for invoicenumber in invoice_numbers: if invoicenumber.parent_key().kind() == RegioManagerTeam.kind(): logging.warn( "Deleting InvoiceNumber Year %s Original last number: %s" % (invoicenumber.key().name(), invoicenumber.last_number)) # Delete InvoiceNumber with parent RegioManagerTeam to_delete.append(invoicenumber) db.delete(to_delete) for invoice in Invoice.all().filter( 'date >', 1460635200 if not DEBUG else 1459870047): # Thu, 14 Apr 2016 12:00:00 GMT def trans(): new_invoice = Invoice(key_name=InvoiceNumber.next( LegalEntity.create_key(invoice.legal_entity_id)), parent=invoice.parent_key()) logging.warn("Creating new Invoice %s" % new_invoice.key().name()) new_invoice.date = invoice.date new_invoice.pdf = invoice.pdf new_invoice.amount = invoice.amount new_invoice.vat_pct = invoice.vat_pct new_invoice.total_amount = invoice.total_amount new_invoice.paid = invoice.paid new_invoice.paid_timestamp = invoice.paid_timestamp new_invoice.payment_type = invoice.payment_type new_invoice.operator = invoice.operator new_invoice.legal_entity_id = invoice.legal_entity_id new_invoice.put() invoice.deleted = True invoice.put() run_in_xg_transaction(trans)
def put_invoices(): all_invoices = list(Invoice.all()) mobicage_legal_entity_id = get_mobicage_legal_entity() for invoices in chunks(all_invoices, 200): to_put = list() for i in invoices: manager = i.operator and RegioManager.get(RegioManager.create_key(i.operator.email())) i.legal_entity_id = manager and manager.team.legal_entity_id or mobicage_legal_entity_id.id if i.paid and i.paid_timestamp is None: i.paid_timestamp = 0 if i.legal_entity_id == mobicage_legal_entity_id.id else now() to_put.append(i) db.put(invoices)
class InvoicePdfHandler(webapp.RequestHandler): def get(self): from shop.models import Customer, Invoice service_user = users.get_current_user() customer_id = long(self.request.get("customer_id")) order_number = self.request.get("order_number") charge_id = long(self.request.get("charge_id")) invoice_number = self.request.get("invoice_number") download = self.request.get("download", "false") == "true" self.response.headers['Content-Type'] = 'application/pdf' self.response.headers['Content-Disposition'] = str( '%s; filename=invoice_%s.pdf' % ("attachment" if download else "inline", invoice_number)) try: customer = Customer.get_by_id(customer_id) except CustomerNotFoundException, exception: logging.exception(exception) self.abort(500) return if customer.service_email != service_user.email(): logging.error("%s attempted to download invoice of %s", service_user, customer.service_email) self.error(500) return invoice = db.get( Invoice.create_key(customer_id, order_number, charge_id, invoice_number)) if not invoice or not invoice.pdf: logging.error( "%s attempted to download invoice %s which does not exist or does not have a pdf generated", service_user, invoice_number) self.error(500) return self.response.out.write(invoice.pdf)
def create_reseller_invoice_for_legal_entity(legal_entity, start_date, end_date, do_send_email=True): """ Args: legal_entity (LegalEntity) start_date (long) end_date (long) do_send_email (bool) """ if legal_entity.is_mobicage: # To avoid a composite index we don't filter on is_mobicage return solution_server_settings = get_solution_server_settings() from_email = solution_server_settings.shop_no_reply_email to_emails = solution_server_settings.shop_payment_admin_emails mobicage_legal_entity = get_mobicage_legal_entity() logging.info( 'Exporting reseller invoices for legal entity %s(id %d) from %s(%s) to %s(%s)', legal_entity.name, legal_entity.id, start_date, time.ctime(start_date), end_date, time.ctime(end_date)) invoices = list(Invoice.all().filter( 'legal_entity_id', legal_entity.id).filter('paid_timestamp >', start_date).filter( 'paid_timestamp <', end_date).filter('paid', True).filter( 'payment_type IN', (Invoice.PAYMENT_MANUAL, Invoice.PAYMENT_MANUAL_AFTER))) start_time = time.strftime('%m/%d/%Y', time.gmtime(int(start_date))) end_time = time.strftime('%m/%d/%Y', time.gmtime(int(end_date))) if not invoices: message = 'No new invoices for reseller %s for period %s - %s' % ( legal_entity.name, start_time, end_time) logging.info(message) if do_send_email: send_mail(from_email, to_emails, message, message) return items_per_customer = {} customers_to_get = set() products = { p.code: p for p in Product.list_by_legal_entity(legal_entity.id) } for invoice in invoices: # get all subscription order items order_items = list(OrderItem.list_by_order(invoice.order_key)) for item in reversed(order_items): product = products[item.product_code] # We're only interested in subscription items if product.is_subscription or product.is_subscription_extension or product.is_subscription_discount: if invoice.customer_id not in items_per_customer: items_per_customer[invoice.customer_id] = [] customers_to_get.add( Customer.create_key(invoice.customer_id)) items_per_customer[invoice.customer_id].append(item) else: order_items.remove(item) if not customers_to_get: message = 'No new invoices containing subscriptions for reseller %s for period %s - %s' % ( legal_entity.name, start_time, end_time) logging.info(message) if do_send_email: send_mail(from_email, to_emails, message, message) return customers = {c.id: c for c in db.get(customers_to_get)} product_totals = {} for customer_id in items_per_customer: items = items_per_customer[customer_id] for item in items: if item.product_code not in product_totals: product_totals[item.product_code] = { 'count': 0, 'price': int(item.price * legal_entity.revenue_percent) } product_totals[item.product_code]['count'] += item.count total_amount = 0 for product in product_totals: p = product_totals[product] price = p['count'] * p['price'] p['total_price'] = format_currency( price / 100., legal_entity.currency_code, locale=mobicage_legal_entity.country_code) total_amount += price total_amount_formatted = format_currency( total_amount / 100., legal_entity.currency_code, locale=mobicage_legal_entity.country_code) vat_amount = total_amount / mobicage_legal_entity.vat_percent if mobicage_legal_entity.country_code == legal_entity.country_code else 0 vat_amount_formatted = format_currency( vat_amount / 100., legal_entity.currency_code, locale=mobicage_legal_entity.country_code) from_date = format_datetime(datetime.utcfromtimestamp(start_date), locale=SHOP_DEFAULT_LANGUAGE, format='dd/MM/yyyy HH:mm') until_date = format_datetime(datetime.utcfromtimestamp(end_date), locale=SHOP_DEFAULT_LANGUAGE, format='dd/MM/yyyy HH:mm') solution_server_settings = get_solution_server_settings() template_variables = { 'products': products, 'customers': customers, 'invoices': invoices, 'items_per_customer': items_per_customer, 'product_totals': product_totals.items(), 'mobicage_legal_entity': mobicage_legal_entity, 'legal_entity': legal_entity, 'language': SHOP_DEFAULT_LANGUAGE, 'from_date': from_date, 'until_date': until_date, 'revenue_percent': legal_entity.revenue_percent, 'vat_amount_formatted': vat_amount_formatted, 'total_amount_formatted': total_amount_formatted, 'logo_path': '../html/img/osa_white_en_250.jpg', 'tos_link': '<a href="%s">%s</a>' % (solution_server_settings.shop_privacy_policy_url, solution_server_settings.shop_privacy_policy_url) } source_html = SHOP_JINJA_ENVIRONMENT.get_template( 'invoice/reseller_invoice.html').render(template_variables) output_stream = StringIO() pisa.CreatePDF(src=source_html, dest=output_stream, path='%s/invoice' % SHOP_TEMPLATES_FOLDER) invoice_pdf_contents = output_stream.getvalue() output_stream.close() # Create an order, order items, charge and invoice. _now = now() customer = legal_entity.get_or_create_customer() mobicage_team = RegioManagerTeam.get_mobicage() def trans(): to_put = list() order_number = OrderNumber.next(mobicage_legal_entity) order_key = db.Key.from_path(Order.kind(), order_number, parent=customer.key()) order = Order(key=order_key) order.contact_id = legal_entity.contact_id order.date = _now order.vat_pct = mobicage_legal_entity.vat_percent if legal_entity.country_code == mobicage_legal_entity.country_code else 0 order.amount = int(round(total_amount)) order.vat = int(round(vat_amount)) order.total_amount = int(round(total_amount + vat_amount)) order.is_subscription_order = False order.is_subscription_extension_order = False order.team_id = mobicage_team.id order.manager = customer.manager order.status = Order.STATUS_SIGNED to_put.append(order) for i, (product_code, item) in enumerate(product_totals.iteritems()): order_item = OrderItem(parent=order_key) order_item.number = i + 1 order_item.comment = products[product_code].default_comment( SHOP_DEFAULT_LANGUAGE) order_item.product_code = product_code order_item.count = item['count'] order_item.price = item['price'] to_put.append(order_item) charge_key = Charge.create_key(allocate_id(Charge), order_number, customer.id) charge = Charge(key=charge_key) charge.date = _now charge.type = Charge.TYPE_ORDER_DELIVERY charge.amount = order.amount charge.vat_pct = order.vat_pct charge.vat = order.vat charge.total_amount = order.total_amount charge.manager = order.manager charge.team_id = order.team_id charge.charge_number = ChargeNumber.next(mobicage_legal_entity) charge.currency_code = legal_entity.currency_code to_put.append(charge) invoice_number = InvoiceNumber.next(mobicage_legal_entity) invoice = Invoice(key_name=invoice_number, parent=charge, amount=charge.amount, vat_pct=charge.vat_pct, vat=charge.vat, total_amount=charge.total_amount, currency_code=legal_entity.currency_code, date=_now, payment_type=Invoice.PAYMENT_MANUAL_AFTER, operator=charge.manager, paid=False, legal_entity_id=mobicage_legal_entity.id, pdf=invoice_pdf_contents) charge.invoice_number = invoice_number to_put.append(invoice) put_and_invalidate_cache(*to_put) return order, charge, invoice order, charge, invoice = run_in_xg_transaction(trans) if do_send_email: serving_url = '%s/internal/shop/invoice/pdf?customer_id=%d&order_number=%s&charge_id=%d&invoice_number=%s' % ( get_server_settings().baseUrl, customer.id, order.order_number, charge.id, invoice.invoice_number) subject = 'New reseller invoice for %s, %s - %s' % ( legal_entity.name, start_time, end_time) body_text = 'A new invoice is available for reseller %s for period %s to %s here: %s' % ( legal_entity.name, start_time, end_time, serving_url) send_mail(from_email, to_emails, subject, body_text)
def trans(): to_put = list() order_number = OrderNumber.next(mobicage_legal_entity) order_key = db.Key.from_path(Order.kind(), order_number, parent=customer.key()) order = Order(key=order_key) order.contact_id = legal_entity.contact_id order.date = _now order.vat_pct = mobicage_legal_entity.vat_percent if legal_entity.country_code == mobicage_legal_entity.country_code else 0 order.amount = int(round(total_amount)) order.vat = int(round(vat_amount)) order.total_amount = int(round(total_amount + vat_amount)) order.is_subscription_order = False order.is_subscription_extension_order = False order.team_id = mobicage_team.id order.manager = customer.manager order.status = Order.STATUS_SIGNED to_put.append(order) for i, (product_code, item) in enumerate(product_totals.iteritems()): order_item = OrderItem(parent=order_key) order_item.number = i + 1 order_item.comment = products[product_code].default_comment( SHOP_DEFAULT_LANGUAGE) order_item.product_code = product_code order_item.count = item['count'] order_item.price = item['price'] to_put.append(order_item) charge_key = Charge.create_key(allocate_id(Charge), order_number, customer.id) charge = Charge(key=charge_key) charge.date = _now charge.type = Charge.TYPE_ORDER_DELIVERY charge.amount = order.amount charge.vat_pct = order.vat_pct charge.vat = order.vat charge.total_amount = order.total_amount charge.manager = order.manager charge.team_id = order.team_id charge.charge_number = ChargeNumber.next(mobicage_legal_entity) charge.currency_code = legal_entity.currency_code to_put.append(charge) invoice_number = InvoiceNumber.next(mobicage_legal_entity) invoice = Invoice(key_name=invoice_number, parent=charge, amount=charge.amount, vat_pct=charge.vat_pct, vat=charge.vat, total_amount=charge.total_amount, currency_code=legal_entity.currency_code, date=_now, payment_type=Invoice.PAYMENT_MANUAL_AFTER, operator=charge.manager, paid=False, legal_entity_id=mobicage_legal_entity.id, pdf=invoice_pdf_contents) charge.invoice_number = invoice_number to_put.append(invoice) put_and_invalidate_cache(*to_put) return order, charge, invoice
def checkout(request): # if cart is empty redirect back to cart page- don't go to checkout if request.cart.is_empty(): return HttpResponseRedirect('/cart/') checkout_step = request.session.get('checkout_step', 1) if request.method == 'POST': action = request.POST.get('action') if action == 'back': if checkout_step == 1: if 'checkout_step' in request.session: del request.session['checkout_step'] if 'token' in request.session: del request.session['token'] if 'invoice' in request.session: del request.session['invoice'] return HttpResponseRedirect('/cart/') if checkout_step > 1: request.session['checkout_step'] = checkout_step - 1 return HttpResponseRedirect('/cart/checkout/') if checkout_step == 1: if request.method == "POST": form = CheckoutForm(data=request.POST) if form.is_valid(): # if the form was valid, proceed to checkout step two. # make sure to save stripe token and order information somewhere! token = stripe.Token.retrieve(request.POST.get('stripe_token')) request.session['token'] = token invoice = Invoice() invoice.name_first = form.cleaned_data['first_name'] invoice.name_last = form.cleaned_data['last_name'] invoice.street_1 = form.cleaned_data['address_1'] invoice.street_2 = form.cleaned_data['address_2'] invoice.city = form.cleaned_data['city'] invoice.country = form.cleaned_data['country'] invoice.province = form.cleaned_data['province'] invoice.postal_code = form.cleaned_data['postal_code'] invoice.phone = form.cleaned_data['phone_number'] invoice.email = form.cleaned_data['email'] invoice.stripe_token = request.POST.get('stripe_token') invoice.card_last4 = token['card']['last4'] invoice.card_brand = token['card']['brand'] # convert the Invoice into a dictionary for serialization into session (we'll change it back later) request.session['invoice'] = model_to_dict(invoice) request.session['checkout_step'] = 2 return HttpResponseRedirect("/cart/checkout/") else: invoice_dict = request.session.get('invoice') initial = {} if invoice_dict: invoice = Invoice(**invoice_dict) initial['first_name'] = invoice.name_first initial['last_name'] = invoice.name_last initial['address_1'] = invoice.street_1 initial['address_2'] = invoice.street_2 initial['city'] = invoice.city initial['country'] = invoice.country initial['province'] = invoice.province initial['postal_code'] = invoice.postal_code initial['phone_number'] = invoice.phone initial['email'] = invoice.email form = CheckoutForm(initial=initial) context = {'form': form} return render(request, 'shop/checkout_step_1.html', context) # process checkout step 2 elif checkout_step == 2: invoice_dict = request.session['invoice'] invoice = Invoice(**invoice_dict) # handle confirm page submitted if request.method == 'POST': with transaction.atomic(): # set the calculated fields and save invoice.shipping = Decimal("10.00") invoice.tax = request.cart.tax() invoice.subtotal = request.cart.subtotal() invoice.total = request.cart.total() + invoice.shipping invoice.save() invoice.create_items(cart=request.cart) request.cart.adjust_stock() total_cents = int(invoice.total * 100) stripe.Charge.create(amount=total_cents, currency='cad', source=invoice.stripe_token, description='Test Charge from checkout') del request.session['checkout_step'] del request.session['invoice'] del request.session['token'] request.cart.delete() # create invoice, # charge stripe token for cart total amount in cents # remove stock from inventory # clear checkout step from session # clear invoice from session invoice.send_email() messages.success(request, "Invoice Successfully sent.") return HttpResponseRedirect('/invoices/%s/' % invoice.id) else: # use some dictionary unpacking magic to turn our invoice_dict back into an Invoice context = {'invoice': invoice, 'token': request.session['token']} return render(request, 'shop/checkout_step_2.html', context)
def export_invoices(year, month): start_date = datetime.date(year, month, 1) end_date = start_date + relativedelta(months=1) qry = Invoice.all() \ .filter('date >=', get_epoch_from_datetime(start_date)) \ .filter('date <', get_epoch_from_datetime(end_date)) invoices = list() order_keys = set() all_products = dict(((p.code, p) for p in Product.all())) for invoice_model in qry: i = model_to_dict(invoice_model) order_key = invoice_model.parent_key().parent() i['invoice_number'] = invoice_model.invoice_number i['order_items'] = map(model_to_dict, OrderItem.all().ancestor(order_key)) if invoice_model.charge.is_recurrent: # only apply recurrent charges for order_item in reversed(i['order_items']): order_item[ 'count'] = invoice_model.charge.subscription_extension_length or 1 product = all_products[order_item['product_code']] if not (product.is_subscription_discount or product.is_subscription or product.is_subscription_extension): i['order_items'].remove(order_item) # add the subscription extensions like XCTY if invoice_model.charge.subscription_extension_order_item_keys: known_extension_item_keys = [ item['_key'] for item in i['order_items'] ] extension_order_items = db.get( invoice_model.charge.subscription_extension_order_item_keys ) for item in extension_order_items: item.count = 1 if str(item.key()) not in known_extension_item_keys: i['order_items'].append(model_to_dict(item)) i['order_key'] = order_key i['currency'] = invoice_model.currency_code order_keys.add(order_key) invoices.append(i) orders = {o.key(): o for o in db.get(order_keys)} contact_keys = set() customer_keys = set() for i in invoices: order_model = orders[i['order_key']] del i['order_key'] i['customer_key'] = order_model.customer_key i['contact_key'] = order_model.contact_key i['manager'] = None if not order_model.manager else order_model.manager.email( ) customer_keys.add(order_model.customer_key) contact_keys.add(order_model.contact_key) del orders customer_and_contact_models = { m.key(): m for m in db.get(customer_keys.union(contact_keys)) } # filter invoices for customers of resellers reseller_ids = [ k.id() for k in LegalEntity.list_non_mobicage(keys_only=True) ] reseller_team_ids = [ t.id for t in RegioManagerTeam.all().filter('legal_entity_id IN', reseller_ids) ] for i in reversed(invoices): customer_model = customer_and_contact_models[i['customer_key']] if customer_model.team_id in reseller_team_ids: invoices.remove(i) continue del i['customer_key'] i['customer'] = model_to_dict(customer_model) contact_model = customer_and_contact_models[i['contact_key']] del i['contact_key'] i['contact'] = model_to_dict(contact_model) del customer_and_contact_models return sorted(invoices, key=lambda i: int(i['invoice_number'].split('.')[-1]))
def getPostCart(request): # User needs to be logged in, or exits the method and returns -1 if not request.user.is_authenticated: return HttpResponse('{"status_code": -1, "message": "Login required"}', content_type='application/json') if request.method == 'GET': try: # Query for the 'cart' status invoice. If there isn't one, create one cart_list = Invoice.objects.filter(status_id=1, user_id=request.user.id) if len(cart_list) == 0: cart = Invoice(date=datetime.now(), user_id=request.user.id, status_id=1) # If there is an existing cart, use that else: cart = cart_list[0] # Query for every item existing in the cart lineItems = LineItem.objects.filter(invoice_id=cart.invoice_id) # Create an empty array with the length equivalent to existing line items in cart data = [None] * len(lineItems) # Create dict of line items in cart and append them to the empty array created above for i in range(0, len(lineItems)): # Per one item, query for its item name and item image item = Item.objects.get(item_id=lineItems[i].item_id) item_name = item.name item_image = item.image data[i] = { 'line_item_id': lineItems[i].line_item, 'invoice_id': lineItems[i].invoice_id, 'item_id': lineItems[i].item_id, 'item_name': item_name, 'item_image': str(item_image), 'line_item_price': float(lineItems[i].line_item_price), 'quantity': lineItems[i].quantity, 'status': lineItems[i].status_id } # Convert the array into transferable json data data = json.dumps(data) print('Successfully fetched line items from current cart') # Return the json data return HttpResponse(data, content_type='application/json') except (KeyError): return HttpResponse('{"status_code": -6, "message": "Key error"}', content_type='application/json') elif request.method == 'POST': try: # Retrieve data from user request data = json.loads(request.body) # Cart current_cart = queryCart(request) # Check if the picked item belongs to the current logged in user. If so, terminate process and throw an error code item_id = data['item_id'] item_owner_id = Item.objects.get(item_id=item_id).user_id current_user_id = request.user.id if item_owner_id == current_user_id: return HttpResponse( '{"status_code": -10, "message": "Attempted to add own item into cart"}', content_type='application/json') # Check if item_id input is of the right data type: int # try: # int(data['item_id']) # except: # return HttpResponse('-7', content_type='application/json') if not type(data['item_id']) == int: return HttpResponse( '{"status_code": -7, "message": "Wrong data type input"}', content_type='application/json') # Check if there is already an entry with line_item_id of the data sent by the user original_entry_list = LineItem.objects.filter( item_id=data['item_id'], invoice_id=current_cart.invoice_id) # If there is already a same lineitem existing in cart, this is an update to quantity # Update if len(original_entry_list) > 0: original_entry = original_entry_list[0] if 'quantity' in data.keys(): # Check if quantity input is of right data type: int if not type(data['quantity']) == int: return HttpResponse( '{"status_code": -7, "message": "Wrong data type input"}', content_type='application/json') original_entry.quantity = data['quantity'] original_entry.line_item_price = updateLineItemPrice( original_entry.quantity, original_entry.item_id) original_entry.save() # If there is no line_item with the same line_item_id in cart, it's a post # Post(Putting items into your cart) else: # Query for this user's cart cart = Invoice.objects.get(status_id=1, user_id=request.user.id) invoice_id = cart.invoice_id item_id = data['item_id'] quantity = data['quantity'] # Check if both of the passed in data are of the right type: int if not type(item_id) == int or not type(quantity) == int: return HttpResponse( '{"status_code": -7, "message": "Wrong data type input"}', content_type='application/json') # Calculate the total line_item_price line_item_price = updateLineItemPrice(quantity, item_id) # Create and save new lineitem data new_line_item = LineItem(status_id=1, invoice_id=invoice_id, item_id=item_id, line_item_price=line_item_price, quantity=quantity) new_line_item.save() print('The lineItem has been added to the cart successfully') return HttpResponse('{"status_code": 0, "message": "Success"}', content_type='application/json') except (KeyError): print("There was a key error") return HttpResponse('{"status_code": -6, "message": "Key error"}', content_type='application/json')
def delete_deleted_invoices(): db.delete(Invoice.all(keys_only=True).filter('deleted', True)) logging.error("Please remove the Invoice.deleted property")
def trans(): new_invoice = Invoice(key_name=InvoiceNumber.next( LegalEntity.create_key(invoice.legal_entity_id)), parent=invoice.parent_key()) logging.warn("Creating new Invoice %s" % new_invoice.key().name()) new_invoice.date = invoice.date new_invoice.pdf = invoice.pdf new_invoice.amount = invoice.amount new_invoice.vat_pct = invoice.vat_pct new_invoice.total_amount = invoice.total_amount new_invoice.paid = invoice.paid new_invoice.paid_timestamp = invoice.paid_timestamp new_invoice.payment_type = invoice.payment_type new_invoice.operator = invoice.operator new_invoice.legal_entity_id = invoice.legal_entity_id new_invoice.put() invoice.deleted = True invoice.put()
def checkout(request): # if cart is empty redirect back to cart page- don't go to checkout if request.cart.is_empty(): return HttpResponseRedirect('/cart/') checkout_step = request.session.get('checkout_step', 1) if request.method == 'POST': action = request.POST.get('action') if action == 'back': if checkout_step == 1: if 'checkout_step' in request.session: del request.session['checkout_step'] if 'token' in request.session: del request.session['token'] if 'invoice' in request.session: del request.session['invoice'] return HttpResponseRedirect('/cart/') if checkout_step > 1: request.session['checkout_step'] = checkout_step - 1 return HttpResponseRedirect('/cart/checkout/') if checkout_step == 1: if request.method == "POST": form = CheckoutForm(data=request.POST) if form.is_valid(): # if the form was valid, proceed to checkout step two. # make sure to save stripe token and order information somewhere! token = stripe.Token.retrieve(request.POST.get('stripe_token')) request.session['token'] = token invoice = Invoice() invoice.name_first = form.cleaned_data['first_name'] invoice.name_last = form.cleaned_data['last_name'] invoice.street_1 = form.cleaned_data['address_1'] invoice.street_2 = form.cleaned_data['address_2'] invoice.city = form.cleaned_data['city'] invoice.country = form.cleaned_data['country'] invoice.province = form.cleaned_data['province'] invoice.postal_code = form.cleaned_data['postal_code'] invoice.phone = form.cleaned_data['phone_number'] invoice.email = form.cleaned_data['email'] invoice.stripe_token = request.POST.get('stripe_token') invoice.card_last4 = token['card']['last4'] invoice.card_brand = token['card']['brand'] # convert the Invoice into a dictionary for serialization into session (we'll change it back later) request.session['invoice'] = model_to_dict(invoice) request.session['checkout_step'] = 2 return HttpResponseRedirect("/cart/checkout/") else: invoice_dict = request.session.get('invoice') initial = {} if invoice_dict: invoice = Invoice(**invoice_dict) initial['first_name'] = invoice.name_first initial['last_name'] = invoice.name_last initial['address_1'] = invoice.street_1 initial['address_2'] = invoice.street_2 initial['city'] = invoice.city initial['country'] = invoice.country initial['province'] = invoice.province initial['postal_code'] = invoice.postal_code initial['phone_number'] = invoice.phone initial['email'] = invoice.email form = CheckoutForm(initial=initial) context = {'form': form} return render(request, 'shop/checkout_step_1.html', context) # process checkout step 2 elif checkout_step == 2: invoice_dict = request.session['invoice'] invoice = Invoice(**invoice_dict) # handle confirm page submitted if request.method == 'POST': with transaction.atomic(): # set the calculated fields and save invoice.shipping = Decimal("10.00") invoice.tax = request.cart.tax() invoice.subtotal = request.cart.subtotal() invoice.total = request.cart.total() + invoice.shipping invoice.save() invoice.create_items(cart=request.cart) request.cart.adjust_stock() total_cents = int(invoice.total*100) stripe.Charge.create( amount=total_cents, currency='cad', source=invoice.stripe_token, description='Test Charge from checkout' ) del request.session['checkout_step'] del request.session['invoice'] del request.session['token'] request.cart.delete() # create invoice, # charge stripe token for cart total amount in cents # remove stock from inventory # clear checkout step from session # clear invoice from session invoice.send_email() messages.success(request, "Invoice Successfully sent.") return HttpResponseRedirect('/invoices/%s/' % invoice.id) else: # use some dictionary unpacking magic to turn our invoice_dict back into an Invoice context = { 'invoice': invoice, 'token': request.session['token'] } return render(request, 'shop/checkout_step_2.html', context)
def import_stock(self, ws): """ Read stock sheet, create missing items, update purchases and invoices """ self.stdout.write(">> Start import stock") # Item.objects.filter(category__isnull=True).delete() # Purchase.objects.all().delete() rowgen = ws.rows cols = [c.value for c in next(rowgen)] try: col_pdate = cols.index("Pdate") col_vendor = cols.index("Vendor") col_vat = cols.index("VAT") col_lot = cols.index("Lot No.") col_prem = cols.index("Prem") col_cost_lot = cols.index("CostLot") col_cost_item = cols.index("CostItem") col_cost_rest = cols.index("Cost Rest") col_stock_no = cols.index("Stock no.") col_description = cols.index("Description") col_price = cols.index("Price") col_sale_date = cols.index("SaleDate") col_inv_no = cols.index("InvNo") col_purchaser = cols.index("Purchaser") col_section = cols.index("Section Text") except ValueError as e: self.stdout.write(f"Header error in sheet {ws.title}:\n{str(e)}") raise exists = 0 created = 0 vendors_created = 0 inv_created = 0 last_vendor = None last_pdate = None try: for row in rowgen: row_number = row[0].row ref = str(row[col_stock_no].value) if ref[0].isdigit(): ref = "#" + ref description = row[col_description].value price, text = parse_decimal(row[col_price].value) if text: self.stdout.write( f"Ignoring row: {row[0].row} Price = {text}") continue inv_no = row[col_inv_no].value sale_date = row[col_sale_date].value archive = False if inv_no and sale_date: archive = True sale_date = parse_date(sale_date) vat, _ = parse_decimal(row[col_vat].value) margin_scheme = not vat lot_number = row[col_lot].value cost_item, _ = parse_decimal(row[col_cost_item].value) cost_lot, _ = parse_decimal(row[col_cost_lot].value) cost_rest, _ = parse_decimal(row[col_cost_rest].value) premium, _ = parse_decimal(row[col_prem].value) pdate = parse_date(row[col_pdate].value) vendor_name = parse_special(row[col_vendor].value) # Find or create a vendor vendor = None if vendor_name: key = vendor_key(vendor_name) vendors = Contact.objects.filter(notes=key) l = len(vendors) if l == 0: name, address = parse_name_address(vendor_name, vendor=True) vendor = Contact.objects.create(company=name, notes=key, vendor=True) address = Address.objects.create(address=address, contact=vendor) vendor.main_address = address vendor.save() vendors_created += 1 elif l == 1: vendor = vendors[0] else: self.stdout.write( f"Info row: {row_number} Multiple vendors {l}: {vendor}" ) else: # Missing vendor uses previous vendor if same purchase date vendor = last_vendor # if last_pdate == pdate: # self.stdout.write( # f"Info row: {row_number} {vendor.name} different date" # ) # Find or create an item and add costs item = None try: item = Item.objects.get(ref=ref) if not item.sale_price: item.sale_price = 0 if item.sale_price != price: if not item.archive: self.stdout.write( f"Info row: {row_number} Web price: {item.sale_price} Excel price: {price}" ) exists += 1 except Item.DoesNotExist: self.stdout.write(f"Item {ref} {description} not found") item = Item.objects.create( name=truncate(description), ref=ref, description=description, sale_price=Decimal(price), category=None, image=None, archive=archive, visible=False, ) created += 1 if item: item.cost_price = cost_item item.restoration_cost = cost_rest # Create a purchase record and link item to it try: purchase = Purchase.objects.get(vendor=vendor, date=pdate) except Purchase.DoesNotExist: purchase = Purchase.objects.create( date=pdate, invoice_number=0, invoice_total=0, buyers_premium=premium, vendor=vendor, margin_scheme=margin_scheme, vat=vat, ) # Find or create a lot try: lot = Lot.objects.get(purchase=purchase, number=lot_number) except Lot.DoesNotExist: lot = Lot.objects.create(purchase=purchase, number=lot_number, cost=cost_lot) item.lot = lot # if sold, update invoice with item if inv_no: try: invoice = Invoice.objects.get(number=inv_no) item.invoice = invoice except Invoice.DoesNotExist: invoice = Invoice( date=pdate, number=inv_no, buyer=None, total=0, paid=True, ) inv_created += 1 item.invoice = invoice print(invoice.total, item.sale_price) invoice.total += item.sale_price invoice.save() item.save() last_pdate = pdate last_vendor = vendor except Exception as e: self.stdout.write( f"Exception in {ws.title} row {row_number}\n{str(e)}") raise # Calculate the invoice total for every purchase for purchase in Purchase.objects.all(): total = purchase.buyers_premium for lot in purchase.lot_set.all(): total += lot.cost purchase.invoice_total = total purchase.save() self.stdout.write( f"Items exists: {exists} Created: {created} Vendors created {vendors_created} Invoices created: {inv_created}" )
def submitCart(request): # Check if a user is logged in if not request.user.is_authenticated: return HttpResponse('{"status_code": -1, "message": "Login required"}', content_type='application/json') # Query and check if there are more item stocks than requested quantity of the line item # Query and change the status for every line item that was in the cart to 2 # Get the id of current cart current_cart_id = Invoice.objects.get( status_id=1, user_id=request.user.id).invoice_id line_items_in_cart = LineItem.objects.filter( invoice=current_cart_id) # Query for line items that has a status of 2(not saved) line_items_in_cart_not_saved = LineItem.objects.filter( invoice=current_cart_id, status_id=1) # If there are no items ready for purchase in the cart, abort submitting if len(line_items_in_cart_not_saved) == 0: return HttpResponse('{"status_code": -11, "message": "No line item with status 1 to submit"}', content_type='application/json') # Do stock check first here and return -1 error if stock is less than quantity for line_item in line_items_in_cart: item_id = line_item.item_id quantity = line_item.quantity item_stock = Item.objects.get(item_id=item_id).stock if item_stock < quantity: # Create and save notification item for this user new_notification = Notification( notification_body="There are not enough stocks of this item.", user=request.user, line_item_id=line_item.line_item) new_notification.save() return HttpResponse('{"status_code": -2, "message": "Not enough stock"}', content_type='application/json') # Create a new cart under this user's user_id new_cart = Invoice(user=request.user, status_id=1, date=datetime.now()) new_cart.save() # Change status for lineitem and stocks for item for line_item in line_items_in_cart: # Query for the item of the line_item item_id = line_item.item_id quantity = line_item.quantity status = line_item.status_id item = Item.objects.get(item_id=item_id) seller_id = item.user_id # If there are more stocks than requested quantity, # and the status of the item is 1, # go through with changing the status and calculating the item stocks if status == 1: line_item.status_id = 2 # Create a notification and send it to the seller of the item seller_notification = Notification( user_id=seller_id, notification_body="A buyer would like to purchase this item.", line_item_id=line_item.line_item) seller_notification.save() line_item.save() # update the stock of the item and save the item item.stock = item.stock - quantity item.save() # Change invoice_id of the line_item with a status of 6 to the one of the new cart elif status == 5: # Newly created cart new_cart = Invoice.objects.filter( user_id=request.user.id, status_id=1).order_by('-invoice_id')[0] line_item.invoice_id = new_cart.invoice_id line_item.save() # Query for the invoice with status of cart(1) and switch the status to paid(2) # Don't exactly now why this query gets more than 1? Maybe it didn't? cart = Invoice.objects.get( status_id=1, user_id=request.user.id, invoice_id=current_cart_id) cart.status_id = 2 cart.save() return HttpResponse('{"status_code": 0, "message": "Success"}', content_type='application/json')