def mutate(cls, root, info, id, input): restock = input.get('restock') fulfillment = get_node(info, id, only_type=Fulfillment) order = fulfillment.order errors = [] if not fulfillment.can_edit(): errors.append( Error( field='fulfillment', message=pgettext_lazy( 'Cancel fulfillment mutation error', 'This fulfillment can\'t be canceled'))) if errors: return cls(errors=errors) cancel_fulfillment(fulfillment, restock) if restock: msg = npgettext_lazy( 'Dashboard message', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % {'quantity': fulfillment.get_total_quantity()} else: msg = pgettext_lazy( 'Dashboard message', 'Fulfillment #%(fulfillment)s canceled') % { 'fulfillment': fulfillment.composed_id} order.history.create(content=msg, user=info.context.user) return FulfillmentCancel(fulfillment=fulfillment)
def mutate(cls, root, info, id, input): errors = [] restock = input.get('restock') fulfillment = cls.get_node_or_error(info, id, errors, 'id', Fulfillment) if fulfillment: order = fulfillment.order if not fulfillment.can_edit(): err_msg = pgettext_lazy('Cancel fulfillment mutation error', 'This fulfillment can\'t be canceled') cls.add_error(errors, 'fulfillment', err_msg) if errors: return cls(errors=errors) cancel_fulfillment(fulfillment, restock) if restock: msg = npgettext_lazy( 'Dashboard message', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % { 'quantity': fulfillment.get_total_quantity() } else: msg = pgettext_lazy('Dashboard message', 'Fulfillment #%(fulfillment)s canceled') % { 'fulfillment': fulfillment.composed_id } order.history.create(content=msg, user=info.context.user) return FulfillmentCancel(fulfillment=fulfillment)
def action_present(count): return npgettext_lazy( "Action to perform (the instance is currently running)", u"Shut Off Instance", u"Shut Off Instances", count )
def cancel_fulfillment(request, order_pk, fulfillment_pk): orders = Order.objects.confirmed().prefetch_related('fulfillments') order = get_object_or_404(orders, pk=order_pk) fulfillment = get_object_or_404(order.fulfillments, pk=fulfillment_pk) status = 200 form = CancelFulfillmentForm(request.POST or None, fulfillment=fulfillment) if form.is_valid(): msg = pgettext_lazy( 'Dashboard message', 'Fulfillment #%(fulfillment)s canceled') % { 'fulfillment': fulfillment.composed_id} with transaction.atomic(): form.cancel_fulfillment() if form.cleaned_data.get('restock'): restock_msg = npgettext_lazy( 'Dashboard message', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % { 'quantity': fulfillment.get_total_quantity()} order.history.create(content=restock_msg, user=request.user) order.history.create(content=msg, user=request.user) messages.success(request, msg) return redirect('dashboard:order-details', order_pk=order.pk) elif form.errors: status = 400 ctx = {'form': form, 'order': order, 'fulfillment': fulfillment} return TemplateResponse( request, 'dashboard/order/modal/cancel_fulfillment.html', ctx, status=status)
def action_past(count): return npgettext_lazy( "Past action (the instance is currently already Shut Off)", u"Shut Off Instance", u"Shut Off Instances", count )
def action_present(count): return npgettext_lazy( "Action to perform (the volume is currently attached)", u"Detach Volume", u"Detach Volumes", count )
def action_past(count): return npgettext_lazy( "Past action (the volume is currently being detached)", u"Detaching Volume", u"Detaching Volumes", count )
def cancel_order(request, order_pk): order = get_object_or_404(Order.objects.confirmed(), pk=order_pk) status = 200 form = CancelOrderForm(request.POST or None, order=order) if form.is_valid(): msg = pgettext_lazy('Dashboard message', 'Order canceled') with transaction.atomic(): form.cancel_order() if form.cleaned_data.get('restock'): restock_msg = npgettext_lazy( 'Dashboard message', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % {'quantity': order.get_total_quantity()} order.history.create(content=restock_msg, user=request.user) order.history.create(content=msg, user=request.user) messages.success(request, msg) return redirect('dashboard:order-details', order_pk=order.pk) # TODO: send status confirmation email elif form.errors: status = 400 ctx = {'form': form, 'order': order} return TemplateResponse( request, 'dashboard/order/modal/cancel_order.html', ctx, status=status)
def action_past(count): return npgettext_lazy( "Past action (the volume is currently being detached)", "Detaching Volume", "Detaching Volumes", count )
def mutate(cls, root, info, id, input): restock = input.get('restock') fulfillment = get_node(info, id, only_type=Fulfillment) order = fulfillment.order errors = [] if not fulfillment.can_edit(): errors.append( Error(field='fulfillment', message=pgettext_lazy( 'Cancel fulfillment mutation error', 'This fulfillment can\'t be canceled'))) if errors: return cls(errors=errors) cancel_fulfillment(fulfillment, restock) if restock: msg = npgettext_lazy( 'Dashboard message', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % { 'quantity': fulfillment.get_total_quantity() } else: msg = pgettext_lazy('Dashboard message', 'Fulfillment #%(fulfillment)s canceled') % { 'fulfillment': fulfillment.composed_id } order.history.create(content=msg, user=info.context.user) return FulfillmentCancel(fulfillment=fulfillment)
def action_present(count): return npgettext_lazy( "Action to perform (the volume is currently attached)", "Detach Volume", "Detach Volumes", count )
def customer_list(request): customers = ( User.objects .prefetch_related('orders', 'addresses') .select_related('default_billing_address', 'default_shipping_address') .annotate( num_orders=Count('orders', distinct=True), last_order=Max('orders', distinct=True))) form = CustomerSearchForm(request.GET or None, queryset=customers) form_values = [(field.name, field.value() or '') for field in form] if form.is_valid(): customers = form.search() else: customers = customers.filter( orders__status__in=[ OrderStatus.NEW, OrderStatus.PAYMENT_PENDING, OrderStatus.FULLY_PAID]) title = npgettext_lazy( 'Customer list page title', '%d result', 'Results (%d)') % len(customers) customers = get_paginator_items(customers, 30, request.GET.get('page')) ctx = {'customers': customers, 'form': form, 'title': title, 'default_pagination_params': form_values} return TemplateResponse(request, 'dashboard/customer/list.html', ctx)
def cancel_fulfillment(request, order_pk, fulfillment_pk): status = 200 order = get_object_or_404(Order, pk=order_pk) fulfillment = get_object_or_404(order.fulfillments.all(), pk=fulfillment_pk) form = CancelFulfillmentForm(request.POST or None, fulfillment=fulfillment) if form.is_valid(): msg = pgettext_lazy('Dashboard message', 'Fulfillment #%(fulfillment)s canceled') % { 'fulfillment': fulfillment.composed_id } with transaction.atomic(): form.cancel_fulfillment() if form.cleaned_data.get('restock'): restock_msg = npgettext_lazy( 'Dashboard message', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % { 'quantity': fulfillment.get_total_quantity() } order.history.create(content=restock_msg, user=request.user) order.history.create(content=msg, user=request.user) messages.success(request, msg) return redirect('dashboard:order-details', order_pk=order.pk) elif form.errors: status = 400 ctx = {'form': form, 'order': order, 'fulfillment': fulfillment} return TemplateResponse(request, 'dashboard/order/modal/cancel_fulfillment.html', ctx, status=status)
def cancel_order(request, order_pk): status = 200 order = get_object_or_404(Order, pk=order_pk) form = CancelOrderForm(request.POST or None, order=order) if form.is_valid(): msg = pgettext_lazy('Dashboard message', 'Order canceled') with transaction.atomic(): form.cancel_order() if form.cleaned_data.get('restock'): restock_msg = npgettext_lazy( 'Dashboard message', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % { 'quantity': order.get_total_quantity() } order.history.create(content=restock_msg, user=request.user) order.history.create(content=msg, user=request.user) messages.success(request, msg) return redirect('dashboard:order-details', order_pk=order.pk) # TODO: send status confirmation email elif form.errors: status = 400 ctx = {'form': form, 'order': order} return TemplateResponse(request, 'dashboard/order/modal/cancel_order.html', ctx, status=status)
def fulfill_order_lines(request, order_pk): orders = Order.objects.confirmed().prefetch_related('lines') order = get_object_or_404(orders, pk=order_pk) unfulfilled_lines = order.lines.filter( quantity_fulfilled__lt=F('quantity')) status = 200 form = FulfillmentForm( request.POST or None, order=order, instance=Fulfillment()) FulfillmentLineFormSet = modelformset_factory( FulfillmentLine, form=FulfillmentLineForm, extra=len(unfulfilled_lines), formset=BaseFulfillmentLineFormSet) initial = [ {'order_line': line, 'quantity': line.quantity_unfulfilled} for line in unfulfilled_lines] formset = FulfillmentLineFormSet( request.POST or None, queryset=FulfillmentLine.objects.none(), initial=initial) all_forms_valid = all([line_form.is_valid() for line_form in formset]) if all_forms_valid and form.is_valid(): forms_to_save = [ line_form for line_form in formset if line_form.cleaned_data.get('quantity') > 0] if forms_to_save: fulfillment = form.save() quantity_fulfilled = 0 for line_form in forms_to_save: line = line_form.save(commit=False) line.fulfillment = fulfillment line.save() quantity_fulfilled += line_form.cleaned_data.get('quantity') # update to refresh prefetched lines quantity_fulfilled order = orders.get(pk=order_pk) update_order_status(order) msg = npgettext_lazy( 'Dashboard message related to an order', 'Fulfilled %(quantity_fulfilled)d item', 'Fulfilled %(quantity_fulfilled)d items', 'quantity_fulfilled') % { 'quantity_fulfilled': quantity_fulfilled} order.history.create(content=msg, user=request.user) if form.cleaned_data.get('send_mail'): send_fulfillment_confirmation.delay(order.pk, fulfillment.pk) send_mail_msg = pgettext_lazy( 'Dashboard message related to an order', 'Shipping confirmation email was sent to user' '(%(email)s)') % {'email': order.get_user_current_email()} order.history.create(content=send_mail_msg, user=request.user) else: msg = pgettext_lazy( 'Dashboard message related to an order', 'No items fulfilled') messages.success(request, msg) return redirect('dashboard:order-details', order_pk=order.pk) elif form.errors: status = 400 ctx = { 'form': form, 'formset': formset, 'order': order, 'unfulfilled_lines': unfulfilled_lines} template = 'dashboard/order/fulfillment.html' return TemplateResponse(request, template, ctx, status=status)
def __init__(self, *args, **kwargs): self.order = kwargs.pop('order') super().__init__(*args, **kwargs) self.fields['restock'].label = npgettext_lazy( 'Cancel order form action', 'Restock %(quantity)d item', 'Restock %(quantity)d items', number='quantity') % {'quantity': self.order.get_total_quantity()}
def __init__(self, *args, **kwargs): self.fulfillment = kwargs.pop('fulfillment') super().__init__(*args, **kwargs) self.fields['restock'].label = npgettext_lazy( 'Cancel fulfillment form action', 'Restock %(quantity)d item', 'Restock %(quantity)d items', 'quantity') % {'quantity': self.fulfillment.get_total_quantity()}
def __init__(self, *args, **kwargs): self.task = kwargs.pop('task') super().__init__(*args, **kwargs) self.fields['reavail'].label = npgettext_lazy( 'Cancel task form action', 'Reavail %(quantity)d item', 'Reavail %(quantity)d items', number='quantity') % {'quantity': self.task.get_total_quantity()}
def __init__(self, *args, **kwargs): self.fulfillment = kwargs.pop("fulfillment") super().__init__(*args, **kwargs) self.fields["restock"].label = npgettext_lazy( "Cancel fulfillment form action", "Restock %(quantity)d item", "Restock %(quantity)d items", number="quantity", ) % {"quantity": self.fulfillment.get_total_quantity()}
def clean_lines(cls, order_lines, quantities): for order_line, quantity in zip(order_lines, quantities): if quantity > order_line.quantity_unfulfilled: msg = npgettext_lazy( 'Fulfill order line mutation error', 'Only %(quantity)d item remaining to fulfill: %(order_line)s.', 'Only %(quantity)d items remaining to fulfill: %(order_line)s.', number='quantity') % { 'quantity': order_line.quantity_unfulfilled, 'order_line': order_line} raise ValidationError({'order_line_id': msg})
def clean_quantity(self): quantity = self.cleaned_data.get('quantity') task_line = self.cleaned_data.get('task_line') if quantity > task_line.quantity_unfulfilled: raise forms.ValidationError(npgettext_lazy( 'Fulfill task line form error', '%(quantity)d item remaining to fulfill.', '%(quantity)d items remaining to fulfill.', number='quantity') % { 'quantity': task_line.quantity_unfulfilled, 'task_line': task_line}) return quantity
def product_bulk_update(request): form = forms.ProductBulkUpdate(request.POST) if form.is_valid(): form.save() count = len(form.cleaned_data['products']) msg = npgettext_lazy( 'Dashboard message', '%(count)d product has been updated', '%(count)d products have been updated', number='count') % {'count': count} messages.success(request, msg) return redirect('dashboard:product-list')
def clean_quantity(self): quantity = self.cleaned_data.get('quantity') order_line = self.cleaned_data.get('order_line') if quantity > order_line.quantity_unfulfilled: raise forms.ValidationError(npgettext_lazy( 'Fulfill order line form error', '%(quantity)d item remaining to fulfill.', '%(quantity)d items remaining to fulfill.', 'quantity') % { 'quantity': order_line.quantity_unfulfilled, 'order_line': order_line}) return quantity
def clean_lines_quantities(order_lines, quantities): errors = [] for order_line, quantity in zip(order_lines, quantities): if quantity > order_line.quantity_unfulfilled: msg = npgettext_lazy( 'Fulfill order line mutation error', '%(quantity)d item remaining to fulfill.', '%(quantity)d items remaining to fulfill.', 'quantity') % { 'quantity': order_line.quantity_unfulfilled, 'order_line': order_line} errors.append((order_line.variant.name, msg)) return errors
def clean_quantity(self): quantity = self.cleaned_data['quantity'] delta = quantity - self.initial_quantity try: self.variant.check_quantity(delta) except InsufficientStock as e: raise forms.ValidationError( npgettext_lazy( 'Change quantity form error', 'Only %(remaining)d remaining in stock.', 'Only %(remaining)d remaining in stock.', 'remaining') % {'remaining': e.item.get_stock_quantity()}) return quantity
def clean_quantity(self): quantity = self.cleaned_data['quantity'] delta = quantity - self.initial_quantity try: self.variant.check_quantity(delta) except InsufficientStock as e: raise forms.ValidationError( npgettext_lazy('Change quantity form error', 'Only %(remaining)d remaining in stock.', 'Only %(remaining)d remaining in stock.', 'remaining') % {'remaining': e.item.get_stock_quantity()}) return quantity
def clean_quantity(self): quantity = self.cleaned_data['quantity'] delta = quantity - self.initial_quantity stock = self.instance.stock if stock and delta > stock.quantity_available: raise forms.ValidationError( npgettext_lazy( 'Change quantity form error', 'Only %(remaining)d remaining in stock.', 'Only %(remaining)d remaining in stock.', 'remaining') % {'remaining': ( self.initial_quantity + stock.quantity_available)}) return quantity
def clean_lines_quantities(order_lines, quantities): errors = [] for order_line, quantity in zip(order_lines, quantities): if quantity > order_line.quantity_unfulfilled: msg = npgettext_lazy( 'Fulfill order line mutation error', '%(quantity)d item remaining to fulfill.', '%(quantity)d items remaining to fulfill.', 'quantity') % { 'quantity': order_line.quantity_unfulfilled, 'order_line': order_line } errors.append((order_line.variant.name, msg)) return errors
def clean_lines(cls, order_lines, quantities): for order_line, quantity in zip(order_lines, quantities): if quantity > order_line.quantity_unfulfilled: msg = npgettext_lazy( "Fulfill order line mutation error", "Only %(quantity)d item remaining to fulfill: %(order_line)s.", "Only %(quantity)d items remaining to fulfill: %(order_line)s.", number="quantity", ) % { "quantity": order_line.quantity_unfulfilled, "order_line": order_line, } raise ValidationError({"order_line_id": msg})
def product_bulk_update(request): form = forms.ProductBulkUpdate(request.POST) if form.is_valid(): form.save() count = len(form.cleaned_data["products"]) msg = npgettext_lazy( "Dashboard message", "%(count)d product has been updated", "%(count)d products have been updated", number="count", ) % {"count": count} messages.success(request, msg) return redirect("dashboard:product-list")
def clean_quantity(self): quantity = self.cleaned_data['quantity'] delta = quantity - self.initial_quantity variant = self.instance.variant if variant and delta > variant.quantity_available: raise forms.ValidationError( npgettext_lazy( 'Change quantity form error', 'Only %(remaining)d remaining in stock.', 'Only %(remaining)d remaining in stock.', 'remaining') % { 'remaining': ( self.initial_quantity + variant.quantity_available)}) # noqa return quantity
def test_second_before_equal_first_humanize_time_strings(self): time_strings = { 'minute': npgettext_lazy('naturaltime-future', '%d minute', '%d minutes'), } with translation.override('cs'): for now in [ self.t, self.t - self.onemicrosecond, self.t - self.oneday ]: with self.subTest(now): self.assertEqual( timesince(self.t, now, time_strings=time_strings), '0\xa0minut', )
def clean_quantity(self): quantity = self.cleaned_data['quantity'] delta = quantity - self.initial_quantity variant = self.instance.variant if variant and delta > variant.quantity_available: raise forms.ValidationError( npgettext_lazy( 'Change quantity form error', 'Only %(remaining)d remaining in availability.', 'Only %(remaining)d remaining in availability.', number='remaining') % { 'remaining': ( self.initial_quantity + variant.quantity_available)}) # noqa return quantity
def clean_quantity(self): quantity = self.cleaned_data["quantity"] delta = quantity - self.initial_quantity variant = self.instance.variant if variant and delta > variant.quantity_available: raise forms.ValidationError( npgettext_lazy( "Change quantity form error", "Only %(remaining)d remaining in stock.", "Only %(remaining)d remaining in stock.", number="remaining", ) % {"remaining": (self.initial_quantity + variant.quantity_available)} ) # noqa return quantity
def mutate(cls, root, info, id, restock): order = get_node(info, id, only_type=Order) cancel_order(order=order, restock=restock) if restock: restock_msg = npgettext_lazy( 'Dashboard message related to an order', 'Restocked %(quantity)d item', 'Restocked %(quantity)d items', 'quantity') % {'quantity': order.get_total_quantity()} order.history.create(content=restock_msg, user=info.context.user) else: msg = pgettext_lazy( 'Dashboard message related to an order', 'Order canceled') order.history.create(content=msg, user=info.context.user) return OrderCancel(order=order)
def clean_quantity(self): quantity = self.cleaned_data.get("quantity") order_line = self.cleaned_data.get("order_line") if quantity > order_line.quantity_unfulfilled: raise forms.ValidationError( npgettext_lazy( "Fulfill order line form error", "%(quantity)d item remaining to fulfill.", "%(quantity)d items remaining to fulfill.", number="quantity", ) % { "quantity": order_line.quantity_unfulfilled, "order_line": order_line, }) return quantity
def clean_lines(cls, order_lines, quantities, errors): if errors: return errors for order_line, quantity in zip(order_lines, quantities): if quantity > order_line.quantity_unfulfilled: msg = npgettext_lazy( 'Fulfill order line mutation error', 'Only %(quantity)d item remaining to fulfill.', 'Only %(quantity)d items remaining to fulfill.', number='quantity') % { 'quantity': order_line.quantity_unfulfilled, 'order_line': order_line} cls.add_error(errors, order_line, msg) return errors
def clean_lines(cls, task_lines, quantities, errors): if errors: return errors for task_line, quantity in zip(task_lines, quantities): if quantity > task_line.quantity_unfulfilled: msg = npgettext_lazy( 'Fulfill task line mutation error', 'Only %(quantity)d item remaining to fulfill.', 'Only %(quantity)d items remaining to fulfill.', number='quantity') % { 'quantity': task_line.quantity_unfulfilled, 'task_line': task_line } cls.add_error(errors, task_line, msg) return errors
def clean_lines(cls, order_lines, quantities, errors): for order_line, quantity in zip(order_lines, quantities): if quantity <= 0: cls.add_error(errors, order_line, 'Quantity must be larger than 0.') elif quantity > order_line.quantity_unfulfilled: msg = npgettext_lazy( 'Fulfill order line mutation error', 'Only %(quantity)d item remaining to fulfill.', 'Only %(quantity)d items remaining to fulfill.', number='quantity') % { 'quantity': order_line.quantity_unfulfilled, 'order_line': order_line } cls.add_error(errors, order_line, msg) return errors
def clean_quantity(self): quantity = self.cleaned_data.get("quantity") order_line = self.cleaned_data.get("order_line") if quantity > order_line.quantity_unfulfilled: raise forms.ValidationError( npgettext_lazy( "Fulfill order line form error", "%(quantity)d item remaining to fulfill.", "%(quantity)d items remaining to fulfill.", number="quantity", ) % { "quantity": order_line.quantity_unfulfilled, "order_line": order_line, } ) return quantity
def save(cls, info, instance, cleaned_input): order_lines = cleaned_input.get('order_lines') quantities = cleaned_input.get('quantities') super().save(info, instance, cleaned_input) order = instance.order if order_lines and quantities: quantity_fulfilled = 0 lines_to_fulfill = [ (order_line, quantity) for order_line, quantity in zip(order_lines, quantities) if quantity > 0 ] for line in lines_to_fulfill: order_line = line[0] quantity = line[1] fulfill_order_line(order_line, quantity) quantity_fulfilled += quantity fulfillment_lines = [ models.FulfillmentLine(order_line=line[0], fulfillment=instance, quantity=line[1]) for line in lines_to_fulfill ] models.FulfillmentLine.objects.bulk_create(fulfillment_lines) update_order_status(order) msg = npgettext_lazy('Dashboard message related to an order', 'Fulfilled %(quantity_fulfilled)d item', 'Fulfilled %(quantity_fulfilled)d items', 'quantity_fulfilled') % { 'quantity_fulfilled': quantity_fulfilled } order.history.create(content=msg, user=info.context.user) super().save(info, instance, cleaned_input) if cleaned_input.get('notify_customer'): send_fulfillment_confirmation.delay(order.pk, instance.pk) send_mail_msg = pgettext_lazy( 'Dashboard message related to an order', 'Shipping confirmation email was sent to user' '(%(email)s)') % { 'email': order.get_user_current_email() } order.history.create(content=send_mail_msg, user=info.context.user)
def save(cls, info, instance, cleaned_input): order_lines = cleaned_input.get('order_lines') quantities = cleaned_input.get('quantities') super().save(info, instance, cleaned_input) order = instance.order if order_lines and quantities: quantity_fulfilled = 0 lines_to_fulfill = [ (order_line, quantity) for order_line, quantity in zip(order_lines, quantities) if quantity > 0] for line in lines_to_fulfill: order_line = line[0] quantity = line[1] fulfill_order_line(order_line, quantity) quantity_fulfilled += quantity fulfillment_lines = [ models.FulfillmentLine( order_line=line[0], fulfillment=instance, quantity=line[1]) for line in lines_to_fulfill] models.FulfillmentLine.objects.bulk_create(fulfillment_lines) update_order_status(order) msg = npgettext_lazy( 'Dashboard message related to an order', 'Fulfilled %(quantity_fulfilled)d item', 'Fulfilled %(quantity_fulfilled)d items', 'quantity_fulfilled') % { 'quantity_fulfilled': quantity_fulfilled} order.history.create(content=msg, user=info.context.user) super().save(info, instance, cleaned_input) if cleaned_input.get('notify_customer'): send_fulfillment_confirmation.delay(order.pk, instance.pk) send_mail_msg = pgettext_lazy( 'Dashboard message related to an order', 'Shipping confirmation email was sent to user' '(%(email)s)') % {'email': order.get_user_current_email()} order.history.create(content=send_mail_msg, user=info.context.user)
def fulfill_order_lines(request, order_pk): orders = Order.objects.confirmed().prefetch_related("lines") order = get_object_or_404(orders, pk=order_pk) unfulfilled_lines = order.lines.filter(quantity_fulfilled__lt=F("quantity")) status = 200 form = FulfillmentForm(request.POST or None, order=order, instance=Fulfillment()) FulfillmentLineFormSet = modelformset_factory( FulfillmentLine, form=FulfillmentLineForm, extra=len(unfulfilled_lines), formset=BaseFulfillmentLineFormSet, ) initial = [ {"order_line": line, "quantity": line.quantity_unfulfilled} for line in unfulfilled_lines ] formset = FulfillmentLineFormSet( request.POST or None, queryset=FulfillmentLine.objects.none(), initial=initial ) all_line_forms_valid = all([line_form.is_valid() for line_form in formset]) if all_line_forms_valid and formset.is_valid() and form.is_valid(): forms_to_save = [ line_form for line_form in formset if line_form.cleaned_data.get("quantity") > 0 ] if forms_to_save: fulfillment = form.save() quantities = [] order_lines = [] quantity_fulfilled = 0 for line_form in forms_to_save: line = line_form.save(commit=False) line.fulfillment = fulfillment line.save() quantity = line_form.cleaned_data.get("quantity") quantity_fulfilled += quantity quantities.append(quantity) order_lines.append(line) # update to refresh prefetched lines quantity_fulfilled order = orders.get(pk=order_pk) update_order_status(order) msg = npgettext_lazy( "Dashboard message related to an order", "Fulfilled %(quantity_fulfilled)d item", "Fulfilled %(quantity_fulfilled)d items", number="quantity_fulfilled", ) % {"quantity_fulfilled": quantity_fulfilled} events.fulfillment_fulfilled_items_event( order=order, user=request.user, fulfillment_lines=fulfillment.lines.all(), ) if form.cleaned_data.get("send_mail"): send_fulfillment_confirmation_to_customer( order, fulfillment, request.user ) else: msg = pgettext_lazy( "Dashboard message related to an order", "No items fulfilled" ) messages.success(request, msg) return redirect("dashboard:order-details", order_pk=order.pk) elif form.errors: status = 400 ctx = { "form": form, "formset": formset, "order": order, "unfulfilled_lines": unfulfilled_lines, } template = "dashboard/order/fulfillment.html" return TemplateResponse(request, template, ctx, status=status)
def display_order_event(order_event: OrderEvent): """This function is used to keep the backwards compatibility with the old dashboard and new type of order events (storing enums instead of messages) """ event_type = order_event.type params = order_event.parameters if event_type == events.OrderEvents.PLACED_FROM_DRAFT: return pgettext_lazy( "Dashboard message related to an order", "Order placed from draft order" ) if event_type == events.OrderEvents.PAYMENT_VOIDED: return pgettext_lazy( "Dashboard message related to an order", "Payment was voided by %(user_name)s" % {"user_name": order_event.user}, ) if event_type == events.OrderEvents.PAYMENT_REFUNDED: amount = get_money_from_params(params["amount"]) return pgettext_lazy( "Dashboard message related to an order", "Successfully refunded: %(amount)s" % {"amount": prices_i18n.amount(amount)}, ) if event_type == events.OrderEvents.PAYMENT_CAPTURED: amount = get_money_from_params(params["amount"]) return pgettext_lazy( "Dashboard message related to an order", "Successfully captured: %(amount)s" % {"amount": prices_i18n.amount(amount)}, ) if event_type == events.OrderEvents.ORDER_MARKED_AS_PAID: return pgettext_lazy( "Dashboard message related to an order", "Order manually marked as paid" ) if event_type == events.OrderEvents.CANCELED: return pgettext_lazy( "Dashboard message related to an order", "Order was canceled" ) if event_type == events.OrderEvents.FULFILLMENT_RESTOCKED_ITEMS: return npgettext_lazy( "Dashboard message related to an order", "We restocked %(quantity)d item", "We restocked %(quantity)d items", number="quantity", ) % {"quantity": params["quantity"]} if event_type == events.OrderEvents.NOTE_ADDED: return pgettext_lazy( "Dashboard message related to an order", "%(user_name)s added note: %(note)s" % {"note": params["message"], "user_name": order_event.user}, ) if event_type == events.OrderEvents.FULFILLMENT_CANCELED: return pgettext_lazy( "Dashboard message", "Fulfillment #%(fulfillment)s canceled by %(user_name)s", ) % {"fulfillment": params["composed_id"], "user_name": order_event.user} if event_type == events.OrderEvents.FULFILLMENT_FULFILLED_ITEMS: return pgettext_lazy( "Dashboard message related to an order", "Fulfilled some items" ) if event_type == events.OrderEvents.PLACED: return pgettext_lazy( "Dashboard message related to an order", "Order was placed" ) if event_type == events.OrderEvents.ORDER_FULLY_PAID: return pgettext_lazy( "Dashboard message related to an order", "Order was fully paid" ) if event_type == events.OrderEvents.EMAIL_SENT: return pgettext_lazy( "Dashboard message related to an order", "%(email_type)s email was sent to the customer " "(%(email)s)", ) % { "email_type": EMAIL_CHOICES[params["email_type"]], "email": params["email"], } if event_type == events.OrderEvents.TRACKING_UPDATED: return pgettext_lazy( "Dashboard message related to an order", "Fulfillment #%(fulfillment)s tracking was updated to" " %(tracking_number)s by %(user_name)s", ) % { "fulfillment": params["composed_id"], "tracking_number": params["tracking_number"], "user_name": order_event.user, } if event_type == events.OrderEvents.DRAFT_CREATED: return pgettext_lazy( "Dashboard message related to an order", "The draft was created by %(user_name)s", ) % {"user_name": order_event.user} if event_type == events.OrderEvents.DRAFT_ADDED_PRODUCTS: return pgettext_lazy( "Dashboard message related to an order", "%(user_name)s added some products" ) % {"user_name": order_event.user} if event_type == events.OrderEvents.DRAFT_REMOVED_PRODUCTS: return pgettext_lazy( "Dashboard message related to an order", "%(user_name)s removed some products", ) % {"user_name": order_event.user} if event_type == events.OrderEvents.OVERSOLD_ITEMS: return pgettext_lazy( "Dashboard message related to an order", "%(user_name)s placed the order by bypassing oversold items", ) % {"user_name": order_event.user} if event_type == events.OrderEvents.UPDATED_ADDRESS: return pgettext_lazy( "Dashboard message related to an order", "The order address was updated by %(user_name)s", ) % {"user_name": order_event.user} if event_type == events.OrderEvents.PAYMENT_FAILED: return pgettext_lazy( "Dashboard message related to an order", "The payment was failed by %(user_name)s", ) % {"user_name": order_event.user} if event_type == events.OrderEvents.OTHER: return order_event.parameters["message"] raise ValueError("Not supported event type: %s" % (event_type))
from django.conf import settings from django.utils.translation import npgettext_lazy, ugettext_lazy as _ from yummy.utils import import_module_member # contains id of unit (used in models as choices in Choicesfield), translation function # based npgettext_lazy, optional shortcut of unit and required form for translation if amount # is decimal number (standard number for npgettext_lazy or char 'm' for magic transormation that use # 1 if setting ALLOW_MAGIC_UNITS_TRANSFORM is Flase else 5 and slugify last char of returned val # from npgettext_lazy) UNITS = ( (0, lambda c=1: npgettext_lazy('unit', 'piece', 'pieces', c), lambda c=1: npgettext_lazy('unit', 'pc', 'pcs', c), 'm'), (1, lambda c=1: npgettext_lazy('unit', 'gram', 'grams', c), 'g', 'm'), (2, lambda c=1: npgettext_lazy('unit', 'dekagram', 'dekagrams', c), 'dkg', 'm'), (3, lambda c=1: npgettext_lazy('unit', 'kilogram', 'kilograms', c), 'kg', 'm'), (4, lambda c=1: npgettext_lazy('unit', 'mililiter', 'mililiters', c), 'ml', 'm'), (5, lambda c=1: npgettext_lazy('unit', 'deciliter', 'deciliters', c), 'dl', 'm'), (6, lambda c=1: npgettext_lazy('unit', 'liter', 'liters', c), 'l', 'm'), (7, lambda c=1: npgettext_lazy('unit', 'packaging', 'packagings', c), 'pack', 1), #baleni (8, lambda c=1: npgettext_lazy('unit', 'package', 'packages', c), 'pkg', 'm'), #balicek (9, lambda c=1: npgettext_lazy('unit', 'part', 'parts', c), 'bit', 'm'), #dilek (10, lambda c=1: npgettext_lazy('unit', 'cup', 'cups', c), 'm'), #hrnek (11, lambda c=1: npgettext_lazy('unit', 'handful', 'handful', c), 2), #hrst (12, lambda c=1: npgettext_lazy('unit', 'drop', 'drops', c), 2), #kapka (13, lambda c=1: npgettext_lazy('unit', 'crubicle', 'crubicles', c), 'm'), #kelimek (14, lambda c=1: npgettext_lazy('unit', 'can', 'cans', c), 2), #plechovka (15, lambda c=1: npgettext_lazy('unit', 'scoop', 'scoops', c), 'm'), #kopecek (16, lambda c=1: npgettext_lazy('unit', 'cube', 'cubes', c), 2), #kostka (17, lambda c=1: npgettext_lazy('unit', 'ball', 'balls', c), 2), #kulicka (18, lambda c=1: npgettext_lazy('unit', 'bottle', 'bottles', c), 2), #lahev (19, lambda c=1: npgettext_lazy('unit', 'spoon', 'spoons', c), 1), #lzice
def display_order_event(order_event): """This function is used to keep the backwards compatibility with the old dashboard and new type of order events (storing enums instead of messages) """ event_type = order_event.type params = order_event.parameters if event_type == OrderEvents.PLACED_FROM_DRAFT.value: return pgettext_lazy( 'Dashboard message related to an order', 'Order created from draft order by %(user_name)s' % { 'user_name': order_event.user}) if event_type == OrderEvents.PAYMENT_RELEASED.value: return pgettext_lazy( 'Dashboard message related to an order', 'Payment was released by %(user_name)s' % { 'user_name': order_event.user}) if event_type == OrderEvents.PAYMENT_REFUNDED.value: amount = Money( amount=params['amount'], currency=settings.DEFAULT_CURRENCY) return pgettext_lazy( 'Dashboard message related to an order', 'Successfully refunded: %(amount)s' % { 'amount': prices_i18n.amount(amount)}) if event_type == OrderEvents.PAYMENT_CAPTURED.value: amount = Money( amount=params['amount'], currency=settings.DEFAULT_CURRENCY) return pgettext_lazy( 'Dashboard message related to an order', 'Successfully captured: %(amount)s' % { 'amount': prices_i18n.amount(amount)}) if event_type == OrderEvents.ORDER_MARKED_AS_PAID.value: return pgettext_lazy( 'Dashboard message related to an order', 'Order manually marked as paid by %(user_name)s' % { 'user_name': order_event.user}) if event_type == OrderEvents.CANCELED.value: return pgettext_lazy( 'Dashboard message related to an order', 'Order was canceled by %(user_name)s' % { 'user_name': order_event.user}) if event_type == OrderEvents.FULFILLMENT_RESTOCKED_ITEMS.value: return npgettext_lazy( 'Dashboard message related to an order', 'We restocked %(quantity)d item', 'We restocked %(quantity)d items', 'quantity') % {'quantity': params['quantity']} if event_type == OrderEvents.NOTE_ADDED.value: return pgettext_lazy( 'Dashboard message related to an order', '%(user_name)s added note: %(note)s' % { 'note': params['message'], 'user_name': order_event.user}) if event_type == OrderEvents.FULFILLMENT_CANCELED.value: return pgettext_lazy( 'Dashboard message', 'Fulfillment #%(fulfillment)s canceled by %(user_name)s') % { 'fulfillment': params['composed_id'], 'user_name': order_event.user} if event_type == OrderEvents.FULFILLMENT_FULFILLED_ITEMS.value: return npgettext_lazy( 'Dashboard message related to an order', 'Fulfilled %(quantity_fulfilled)d item', 'Fulfilled %(quantity_fulfilled)d items', 'quantity_fulfilled') % { 'quantity_fulfilled': params['quantity']} if event_type == OrderEvents.PLACED.value: return pgettext_lazy( 'Dashboard message related to an order', 'Order was placed') if event_type == OrderEvents.ORDER_FULLY_PAID.value: return pgettext_lazy( 'Dashboard message related to an order', 'Order was fully paid') if event_type == OrderEvents.EMAIL_SENT.value: return pgettext_lazy( 'Dashboard message related to an order', '%(email_type)s email was sent to the customer ' '(%(email)s)') % { 'email_type': EMAIL_CHOICES[params['email_type']], 'email': params['email']} if event_type == OrderEvents.UPDATED.value: return pgettext_lazy( 'Dashboard message related to an order', 'Order details were updated by %(user_name)s' % { 'user_name': order_event.user}) if event_type == OrderEvents.OTHER.value: return order_event.parameters['message'] raise ValueError('Not supported event type: %s' % (event_type))
def naturaltime(value): """ For date and time values show how many seconds, minutes, or hours ago compared to current timestamp return representing string. """ if not isinstance(value, date): # datetime is a subclass of date return value now = datetime.now(utc if is_aware(value) else None) if value < now: delta = now - value if delta.days != 0: # Translators: delta will contain a string like '2 months' or '1 month, 2 weeks' return _('%(delta)s ago') % {'delta': defaultfilters.timesince(value, now, time_strings={ # Translators: 'naturaltime-past' strings will be included in # '%(delta)s ago' 'year': npgettext_lazy('naturaltime-past', '%d year', '%d years'), 'month': npgettext_lazy('naturaltime-past', '%d month', '%d months'), 'week': npgettext_lazy('naturaltime-past', '%d week', '%d weeks'), 'day': npgettext_lazy('naturaltime-past', '%d day', '%d days'), 'hour': npgettext_lazy('naturaltime-past', '%d hour', '%d hours'), 'minute': npgettext_lazy('naturaltime-past', '%d minute', '%d minutes') })} elif delta.seconds == 0: return _('now') elif delta.seconds < 60: return ngettext( # Translators: please keep a non-breaking space (U+00A0) # between count and time unit. 'a second ago', '%(count)s seconds ago', delta.seconds ) % {'count': delta.seconds} elif delta.seconds // 60 < 60: count = delta.seconds // 60 return ngettext( # Translators: please keep a non-breaking space (U+00A0) # between count and time unit. 'a minute ago', '%(count)s minutes ago', count ) % {'count': count} else: count = delta.seconds // 60 // 60 return ngettext( # Translators: please keep a non-breaking space (U+00A0) # between count and time unit. 'an hour ago', '%(count)s hours ago', count ) % {'count': count} else: delta = value - now if delta.days != 0: # Translators: delta will contain a string like '2 months' or '1 month, 2 weeks' return _('%(delta)s from now') % {'delta': defaultfilters.timeuntil(value, now, time_strings={ # Translators: 'naturaltime-future' strings will be included in # '%(delta)s from now' 'year': npgettext_lazy('naturaltime-future', '%d year', '%d years'), 'month': npgettext_lazy('naturaltime-future', '%d month', '%d months'), 'week': npgettext_lazy('naturaltime-future', '%d week', '%d weeks'), 'day': npgettext_lazy('naturaltime-future', '%d day', '%d days'), 'hour': npgettext_lazy('naturaltime-future', '%d hour', '%d hours'), 'minute': npgettext_lazy('naturaltime-future', '%d minute', '%d minutes') })} elif delta.seconds == 0: return _('now') elif delta.seconds < 60: return ngettext( # Translators: please keep a non-breaking space (U+00A0) # between count and time unit. 'a second from now', '%(count)s seconds from now', delta.seconds ) % {'count': delta.seconds} elif delta.seconds // 60 < 60: count = delta.seconds // 60 return ngettext( # Translators: please keep a non-breaking space (U+00A0) # between count and time unit. 'a minute from now', '%(count)s minutes from now', count ) % {'count': count} else: count = delta.seconds // 60 // 60 return ngettext( # Translators: please keep a non-breaking space (U+00A0) # between count and time unit. 'an hour from now', '%(count)s hours from now', count ) % {'count': count}