def worksheet_setup_a4(worksheet, title1, title2, add_print_title=True): worksheet.title = format_worksheet_title(title1) worksheet.page_setup.paperSize = worksheet.PAPERSIZE_A4 worksheet.page_setup.fitToPage = True worksheet.page_setup.fitToHeight = 0 worksheet.page_setup.fitToWidth = 1 worksheet.print_gridlines = True if add_print_title: worksheet.add_print_title(1, rows_or_cols='rows') worksheet.freeze_panes = 'A2' worksheet.header_footer.left_header.text = Site.objects.get_current().name worksheet.header_footer.left_footer.text = "{}".format(title2) worksheet.header_footer.center_footer.text = "{}".format(title1) worksheet.header_footer.right_footer.text = 'Page &[Page]/&[Pages]' orders_responsible = Staff.get_or_create_order_responsible() invoices_responsible = Staff.get_or_create_invoice_responsible() s1 = EMPTY_STRING if orders_responsible: c = orders_responsible.customer_responsible if c is not None: s1 = "{}: {}, {}".format(_("Orders"), c.long_basket_name, c.phone1) s2 = EMPTY_STRING if invoices_responsible: c = invoices_responsible.customer_responsible if c is not None: s2 = "{}: {}, {}".format(_("Invoices"), c.long_basket_name, c.phone1) separator = chr(10) + " " worksheet.header_footer.right_header.text = separator.join((s1, s2)) return worksheet
def worksheet_setup_a4(worksheet, title1, title2, add_print_title=True): worksheet.title = format_worksheet_title(title1) worksheet.page_setup.paperSize = worksheet.PAPERSIZE_A4 worksheet.page_setup.fitToPage = True worksheet.page_setup.fitToHeight = 0 worksheet.page_setup.fitToWidth = 1 worksheet.print_gridlines = True if add_print_title: worksheet.add_print_title(1, rows_or_cols='rows') worksheet.freeze_panes = 'A2' worksheet.header_footer.left_header.text = Site.objects.get_current().name worksheet.header_footer.left_footer.text = "{}".format(title2) worksheet.header_footer.center_footer.text = "{}".format(title1) worksheet.header_footer.right_footer.text = 'Page &[Page]/&[Pages]' orders_responsible = Staff.get_or_create_order_responsible() invoices_responsible = Staff.get_or_create_invoice_responsible() s1 = EMPTY_STRING if orders_responsible: c = orders_responsible.customer_responsible if c is not None: s1 = "{}: {}{}".format(_("Orders"), c.long_basket_name, c.get_phone1(prefix=", ")) s2 = EMPTY_STRING if invoices_responsible: c = invoices_responsible.customer_responsible if c is not None: s2 = "{}: {}{}".format(_("Invoices"), c.long_basket_name, c.get_phone1(prefix=", ")) separator = chr(10) + " " worksheet.header_footer.right_header.text = separator.join((s1, s2)) return worksheet
def handle(self, *args, **options): if not settings.REPANIER_SETTINGS_DEMO: self.stdout.write(self.style.ERROR("Command not executed because the site is not in DEMO MODE")) exit() translation.activate(settings.LANGUAGE_CODE) config = Configuration.objects.filter(id=DECIMAL_ONE).first() if config is None: exit() config.bank_account = "BE99 9999 9999 9999" config.vat_id = EMPTY_STRING config.save() config.init_email() for customer in Customer.objects.all().order_by('?'): customer.anonymize(also_group=True) customer.user.set_password("customer") customer.user.save() print("Customer anonymized : {}".format(customer)) for staff in Staff.objects.all().order_by('?'): staff.anonymize() print("Staff anonymized : {}".format(staff)) coordinator_password = options['coordinator_password'][0] coordinator_email = options['coordinator_email'][0].lower() coordinator = Staff.get_or_create_any_coordinator() coordinator.user.set_password(coordinator_password) coordinator.user.email = coordinator_email coordinator.user.save() for producer in Producer.objects.all().order_by('?'): producer.anonymize(also_group=True) print("Producer anonymized : {}".format(producer)) for permanence_role in LUT_PermanenceRole.objects.all().order_by('?'): for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] permanence_role.set_current_language(language_code) try: permanence_role.description = EMPTY_STRING permanence_role.save_translations() except TranslationDoesNotExist: pass BankAccount.objects.filter(customer__isnull=False).order_by('?').update(operation_comment=EMPTY_STRING) if options['reset_admin']: self.stdout.write(self.style.SUCCESS("Reset admin to admin/admin")) for user in User.objects.filter(is_superuser=True): str_id = str(user.id) user.username = user.email = "{}@repanier.be".format(str_id) user.first_name = EMPTY_STRING user.last_name = str_id user.is_staff = False user.is_superuser = False user.set_password(None) user.save() User.objects.create_user(username="******", email="*****@*****.**", password="******", first_name=EMPTY_STRING, last_name="admin", is_staff=True, is_superuser=True) self.stdout.write(self.style.SUCCESS("Successfully anonymized customers, staff and producers"))
def worksheet_setup_a4(worksheet, title1, title2, add_print_title=True): worksheet.title = format_worksheet_title(title1) worksheet.page_setup.paperSize = worksheet.PAPERSIZE_A4 worksheet.page_setup.fitToPage = True worksheet.page_setup.fitToHeight = 0 worksheet.page_setup.fitToWidth = 1 worksheet.print_gridlines = True if add_print_title: worksheet.add_print_title(1, rows_or_cols="rows") worksheet.freeze_panes = "A2" worksheet.header_footer.left_header.text = Site.objects.get_current().name worksheet.header_footer.left_footer.text = "{}".format(title2) worksheet.header_footer.center_footer.text = "{}".format(title1) worksheet.header_footer.right_footer.text = "Page &[Page]/&[Pages]" order_responsible = Staff.get_or_create_order_responsible() invoice_responsible = Staff.get_or_create_invoice_responsible() separator = chr(10) + " " worksheet.header_footer.right_header.text = separator.join( (order_responsible["signature"], invoice_responsible["signature"]) ) return worksheet
def export_order_2_1_customer(customer, filename, permanence, order_responsible=None, abstract_ws=None, cancel_order=False): from repanier.apps import \ REPANIER_SETTINGS_GROUP_NAME, \ REPANIER_SETTINGS_SEND_ABSTRACT_ORDER_MAIL_TO_CUSTOMER, \ REPANIER_SETTINGS_CONFIG config = REPANIER_SETTINGS_CONFIG customer_invoice = CustomerInvoice.objects.filter( permanence_id=permanence.id, customer_id=customer.id).order_by('?').first() if customer_invoice is not None: if order_responsible is None: order_responsible = Staff.get_or_create_order_responsible() wb = generate_customer_xlsx(permanence=permanence, customer_invoice=customer_invoice)[0] if wb is not None: to_email = [customer.user.email] if customer.email2: to_email.append(customer.email2) if customer_invoice.delivery is not None: delivery_point = customer_invoice.delivery if delivery_point.delivery_point.inform_customer_responsible and delivery_point.delivery_point.customer_responsible is not None: customer_responsible = delivery_point.delivery_point.customer_responsible if customer_responsible.id != customer.id: to_email.append(customer_responsible.user.email) if customer_responsible.email2: to_email.append(customer_responsible.email2) else: delivery_point = EMPTY_STRING customer_last_balance, customer_on_hold_movement, customer_payment_needed, customer_order_amount = payment_message( customer, permanence) long_basket_name = customer.long_basket_name if customer.long_basket_name is not None else customer.short_basket_name if cancel_order: order_customer_mail = config.safe_translation_getter( 'cancel_order_customer_mail', any_language=True, default=EMPTY_STRING) order_customer_mail_subject = "{} - {} - {}".format( _('⚠ Order cancelled'), REPANIER_SETTINGS_GROUP_NAME, permanence) else: order_customer_mail = config.safe_translation_getter( 'order_customer_mail', any_language=True, default=EMPTY_STRING) order_customer_mail_subject = "{} - {}".format( REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(order_customer_mail) context = TemplateContext({ 'name': long_basket_name, 'long_basket_name': long_basket_name, 'basket_name': customer.short_basket_name, 'short_basket_name': customer.short_basket_name, 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id, )), permanence)), 'last_balance_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0, )), customer_last_balance)), 'last_balance': mark_safe(customer_last_balance), 'order_amount': mark_safe(customer_order_amount), 'on_hold_movement': customer_on_hold_movement, 'payment_needed': mark_safe(customer_payment_needed), 'delivery_point': delivery_point, 'signature': order_responsible.get_html_signature }) html_body = template.render(context) if settings.REPANIER_SETTINGS_CUSTOMER_MUST_CONFIRM_ORDER: to_email = list(set(to_email + order_responsible.get_to_email)) email = RepanierEmail( subject=order_customer_mail_subject, html_body=html_body, from_email=order_responsible.get_from_email, to=to_email, reply_to=order_responsible.get_reply_to_email, show_customer_may_unsubscribe=False, send_even_if_unsubscribed=True) if not cancel_order and REPANIER_SETTINGS_SEND_ABSTRACT_ORDER_MAIL_TO_CUSTOMER: if abstract_ws is not None: wb.add_sheet(abstract_ws, index=0) email.attach( filename, save_virtual_workbook(wb), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) email.send_email()
def open_and_send_offer(self, request, queryset): if "cancel" in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = queryset.first() if permanence.status != PERMANENCE_PLANNED: user_message = _( "The status of %(permanence)s prohibit you to perform this action." ) % { "permanence": permanence } user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return template_offer_mail = [] template_cancel_order_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) with switch_language(repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG.offer_customer_mail) staff = Staff.get_or_create_order_responsible() with switch_language(permanence, language_code): offer_description = permanence.safe_translation_getter( "offer_description", any_language=True, default=EMPTY_STRING) offer_producer = ", ".join( [p.short_profile_name for p in permanence.producers.all()]) qs = Product.objects.filter( producer=permanence.producers.first(), is_into_offer=True, order_unit__lt= PRODUCT_ORDER_UNIT_DEPOSIT, # Don't display technical products. ).order_by("translations__long_name")[:5] offer_detail = "<ul>{}</ul>".format("".join( "<li>{}, {}</li>".format(p.get_long_name(), p.producer.short_profile_name) for p in qs)) context = TemplateContext({ "offer_description": mark_safe(offer_description), "offer_detail": offer_detail, "offer_recent_detail": offer_detail, "offer_producer": offer_producer, "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "signature": staff.get_html_signature, }) template_offer_mail.append(language_code) template_offer_mail.append(template.render(context)) if settings.REPANIER_SETTINGS_CUSTOMER_MUST_CONFIRM_ORDER: context = TemplateContext({ "name": _("Long name"), "long_basket_name": _("Long name"), "basket_name": _("Short name"), "short_basket_name": _("Short name"), "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "signature": staff.get_html_signature, }) template_cancel_order_mail.append(language_code) template_cancel_order_mail.append(template.render(context)) translation.activate(cur_language) email_will_be_sent, email_will_be_sent_to = RepanierEmail.send_email_to_who( ) if "apply" in request.POST or "apply-wo-mail" in request.POST: form = OpenAndSendOfferForm(request.POST) if form.is_valid(): do_not_send_any_mail = "apply-wo-mail" in request.POST # open_order(permanence.id, do_not_send_any_mail) t = threading.Thread(target=open_order, args=(permanence.id, do_not_send_any_mail)) t.start() user_message = _("The offers are being generated.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(request.get_full_path()) else: form = OpenAndSendOfferForm( initial={ "template_offer_customer_mail": mark_safe("<br>==============<br>".join( template_offer_mail)), "template_cancel_order_customer_mail": mark_safe("<br>==============<br>".join( template_cancel_order_mail)), }) template_name = get_repanier_template_name( "confirm_admin_open_and_send_offer.html") return render( request, template_name, { "sub_title": _("Please, confirm the action : open and send offers"), "action_checkbox_name": admin.ACTION_CHECKBOX_NAME, "action": "open_and_send_offer", "permanence": permanence, "form": form, "email_will_be_sent": email_will_be_sent, "email_will_be_sent_to": email_will_be_sent_to, }, )
def open_and_send_offer(self, request, queryset): if 'cancel' in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = queryset.first() if permanence.status not in [PERMANENCE_PLANNED, PERMANENCE_PRE_OPEN]: user_message = _("The status of %(permanence)s prohibit you to perform this action.") % { 'permanence': permanence} user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return pre_open = (permanence.status == PERMANENCE_PLANNED) and Producer.objects.filter( permanence__id=permanence.id, is_active=True, producer_pre_opening=True ).order_by('?').exists() if pre_open: template_offer_mail = [] template_cancel_order_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) with switch_language(repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.offer_producer_mail) staff = Staff.get_or_create_order_responsible() with switch_language(permanence, language_code): offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING ) context = TemplateContext({ 'name': _('Long name'), 'long_profile_name': _('Long name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(_("Offers"))), 'offer_description': mark_safe(offer_description), 'offer_link': mark_safe("<a href=\"#\">{}</a>".format(_("Offers"))), 'signature': staff.get_html_signature, }) template_offer_mail.append(language_code) template_offer_mail.append(template.render(context)) translation.activate(cur_language) email_will_be_sent, email_will_be_sent_to = RepanierEmail.send_email_to_who() else: template_offer_mail = [] template_cancel_order_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) with switch_language(repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.offer_customer_mail) staff = Staff.get_or_create_order_responsible() with switch_language(permanence, language_code): offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING ) offer_producer = ', '.join([p.short_profile_name for p in permanence.producers.all()]) qs = Product.objects.filter( producer=permanence.producers.first(), is_into_offer=True, order_unit__lt=PRODUCT_ORDER_UNIT_DEPOSIT # Don't display technical products. ).order_by( "translations__long_name" )[:5] offer_detail = "<ul>{}</ul>".format("".join("<li>{}, {}</li>".format( p.get_long_name(), p.producer.short_profile_name ) for p in qs ), ) context = TemplateContext({ 'offer_description': mark_safe(offer_description), 'offer_detail': offer_detail, 'offer_recent_detail': offer_detail, 'offer_producer': offer_producer, 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'signature': staff.get_html_signature, }) template_offer_mail.append(language_code) template_offer_mail.append(template.render(context)) if settings.REPANIER_SETTINGS_CUSTOMER_MUST_CONFIRM_ORDER: context = TemplateContext({ 'name': _('Long name'), 'long_basket_name': _('Long name'), 'basket_name': _('Short name'), 'short_basket_name': _('Short name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'signature': staff.get_html_signature, }) template_cancel_order_mail.append(language_code) template_cancel_order_mail.append(template.render(context)) translation.activate(cur_language) email_will_be_sent, email_will_be_sent_to = RepanierEmail.send_email_to_who() if 'apply' in request.POST or 'apply-wo-mail' in request.POST: form = OpenAndSendOfferForm(request.POST) if form.is_valid(): do_not_send_any_mail = 'apply-wo-mail' in request.POST if pre_open: permanence_already_pre_opened = Permanence.objects.filter( status__in=[PERMANENCE_WAIT_FOR_PRE_OPEN, PERMANENCE_PRE_OPEN] ).order_by("-is_updated_on").only("id").first() if permanence_already_pre_opened is not None: user_message = _("A maximum of one permanence may be pre opened.") user_message_level = messages.ERROR else: # pre_open_order(permanence.id) t = threading.Thread(target=pre_open_order, args=(permanence.id,)) t.start() user_message = _("The offers are being generated.") user_message_level = messages.INFO else: # open_order(permanence.id, do_not_send_any_mail) t = threading.Thread(target=open_order, args=(permanence.id, do_not_send_any_mail)) t.start() user_message = _("The offers are being generated.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(request.get_full_path()) else: form = OpenAndSendOfferForm( initial={ 'template_offer_customer_mail': mark_safe( "<br>==============<br>".join(template_offer_mail)), 'template_cancel_order_customer_mail': mark_safe( "<br>==============<br>".join(template_cancel_order_mail)), } ) template_name = get_repanier_template_name( 'confirm_admin_open_and_send_offer.html' ) return render( request, template_name, { 'sub_title': _("Please, confirm the action : open and send offers"), 'action_checkbox_name': admin.ACTION_CHECKBOX_NAME, 'action': 'open_and_send_offer', 'permanence': permanence, 'pre_open': pre_open, 'form': form, 'email_will_be_sent': email_will_be_sent, 'email_will_be_sent_to': email_will_be_sent_to })
def init_repanier(cls): from repanier.const import DECIMAL_ONE, PERMANENCE_NAME_PERMANENCE, CURRENCY_EUR from repanier.models.producer import Producer from repanier.models.bankaccount import BankAccount from repanier.models.staff import Staff from repanier.models.customer import Customer # Create the configuration record managed via the admin UI config = Configuration.objects.filter(id=DECIMAL_ONE).first() if config is not None: return config group_name = settings.REPANIER_SETTINGS_GROUP_NAME site = Site.objects.get_current() if site is not None: site.name = group_name site.domain = group_name site.save() config = Configuration.objects.create( group_name=group_name, name=PERMANENCE_NAME_PERMANENCE, bank_account="BE99 9999 9999 9999", currency=CURRENCY_EUR) config.init_email() config.save() # Create firsts users Producer.get_or_create_group() customer_buyinggroup = Customer.get_or_create_group() very_first_customer = Customer.get_or_create_the_very_first_customer() BankAccount.open_account(customer_buyinggroup=customer_buyinggroup, very_first_customer=very_first_customer) coordinator = Staff.get_or_create_any_coordinator() Staff.get_or_create_order_responsible() Staff.get_or_create_invoice_responsible() # Create and publish first web page if not coordinator.is_webmaster: # This should not be the case... return from cms.models import StaticPlaceholder from cms.constants import X_FRAME_OPTIONS_DENY from cms import api page = api.create_page(title=_("Home"), soft_root=False, template=settings.CMS_TEMPLATE_HOME, language=settings.LANGUAGE_CODE, published=True, parent=None, xframe_options=X_FRAME_OPTIONS_DENY, in_navigation=True) try: # New in CMS 3.5 page.set_as_homepage() except: pass placeholder = page.placeholders.get(slot="home-hero") api.add_plugin(placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_HERO) placeholder = page.placeholders.get(slot="home-col-1") api.add_plugin(placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_COL_1) placeholder = page.placeholders.get(slot="home-col-2") api.add_plugin(placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_COL_2) placeholder = page.placeholders.get(slot="home-col-3") api.add_plugin(placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_COL_3) static_placeholder = StaticPlaceholder(code="footer", # site_id=1 ) static_placeholder.save() api.add_plugin(placeholder=static_placeholder.draft, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body='hello world footer') static_placeholder.publish(request=None, language=settings.LANGUAGE_CODE, force=True) api.publish_page(page=page, user=coordinator.user, language=settings.LANGUAGE_CODE) return config
def export_order_2_1_customer(customer, filename, permanence, order_responsible=None, abstract_ws=None, cancel_order=False): from repanier.apps import \ REPANIER_SETTINGS_SEND_ABSTRACT_ORDER_MAIL_TO_CUSTOMER, \ REPANIER_SETTINGS_CONFIG config = REPANIER_SETTINGS_CONFIG customer_invoice = CustomerInvoice.objects.filter( permanence_id=permanence.id, customer_id=customer.id ).order_by('?').first() if customer_invoice is not None: if order_responsible is None: order_responsible = Staff.get_or_create_order_responsible() wb = generate_customer_xlsx(permanence=permanence, customer_invoice=customer_invoice)[0] if wb is not None: to_email = [customer.user.email] if customer.email2: to_email.append(customer.email2) if customer_invoice.delivery is not None: delivery_point = customer_invoice.delivery if delivery_point.delivery_point.inform_customer_responsible and delivery_point.delivery_point.customer_responsible is not None: customer_responsible = delivery_point.delivery_point.customer_responsible if customer_responsible.id != customer.id: to_email.append(customer_responsible.user.email) if customer_responsible.email2: to_email.append(customer_responsible.email2) else: delivery_point = EMPTY_STRING customer_last_balance, customer_on_hold_movement, customer_payment_needed, customer_order_amount = payment_message( customer, permanence) long_basket_name = customer.long_basket_name if customer.long_basket_name is not None else customer.short_basket_name if cancel_order: order_customer_mail = config.safe_translation_getter( 'cancel_order_customer_mail', any_language=True, default=EMPTY_STRING ) order_customer_mail_subject = "{} - {} - {}".format( _('⚠ Order cancelled'), settings.REPANIER_SETTINGS_GROUP_NAME, permanence) else: order_customer_mail = config.safe_translation_getter( 'order_customer_mail', any_language=True, default=EMPTY_STRING ) order_customer_mail_subject = "{} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(order_customer_mail) context = TemplateContext({ 'name': long_basket_name, 'long_basket_name': long_basket_name, 'basket_name': customer.short_basket_name, 'short_basket_name': customer.short_basket_name, 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)), 'last_balance_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0,)), customer_last_balance)), 'last_balance': mark_safe(customer_last_balance), 'order_amount': mark_safe(customer_order_amount), 'on_hold_movement': customer_on_hold_movement, 'payment_needed': mark_safe(customer_payment_needed), 'delivery_point': delivery_point, 'signature': order_responsible.get_html_signature }) html_body = template.render(context) email = RepanierEmail( subject=order_customer_mail_subject, html_body=html_body, to=to_email, show_customer_may_unsubscribe=False, send_even_if_unsubscribed=True ) if not cancel_order and REPANIER_SETTINGS_SEND_ABSTRACT_ORDER_MAIL_TO_CUSTOMER: if abstract_ws is not None: wb.add_sheet(abstract_ws, index=0) email.attach(filename, save_virtual_workbook(wb), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') email.send_email()
def get_context_data(self, **kwargs): from repanier.apps import REPANIER_SETTINGS_DISPLAY_ANONYMOUS_ORDER_FORM, REPANIER_SETTINGS_CONFIG, \ REPANIER_SETTINGS_NOTIFICATION context = super(OrderView, self).get_context_data(**kwargs) context['first_page'] = self.first_page context['permanence'] = self.permanence context['permanence_id'] = self.permanence.id context["all_dates"] = self.all_dates context["date_id"] = self.date_id context["date_Selected"] = self.date_selected context["notification"] = REPANIER_SETTINGS_NOTIFICATION.get_notification_display() if self.first_page: if settings.REPANIER_SETTINGS_SHOW_PRODUCER_ON_ORDER_FORM: producer_set = Producer.objects.filter(permanence=self.permanence.id).only("id", "short_profile_name") else: producer_set = None context['producer_set'] = producer_set if self.producer_id == 'all': department_set = LUT_DepartmentForCustomer.objects.filter( offeritem__permanence_id=self.permanence.id, offeritem__is_active=True, offeritem__is_box=False) \ .order_by("tree_id", "lft") \ .distinct("id", "tree_id", "lft") else: department_set = LUT_DepartmentForCustomer.objects.filter( offeritem__producer_id=self.producer_id, offeritem__permanence_id=self.permanence.id, offeritem__is_active=True, offeritem__is_box=False) \ .order_by("tree_id", "lft") \ .distinct("id", "tree_id", "lft") context['department_set'] = department_set context['box_set'] = OfferItemWoReceiver.objects.filter( permanence_id=self.permanence.id, is_box=True, is_active=True, may_order=True, translations__language_code=translation.get_language() ).order_by( 'customer_unit_price', 'unit_deposit', 'translations__long_name', ) context['staff_order'] = Staff.get_or_create_order_responsible() if self.is_anonymous: context['how_to_register'] = REPANIER_SETTINGS_CONFIG.safe_translation_getter( 'how_to_register', any_language=True, default=EMPTY_STRING) else: context['how_to_register'] = EMPTY_STRING # use of str() to avoid "12 345" when rendering the template context['producer_id'] = str(self.producer_id) # use of str() to avoid "12 345" when rendering the template context['department_id'] = str(self.department_id) context['box_id'] = str(self.box_id) context['is_box'] = "yes" if self.is_box else EMPTY_STRING if self.is_box: offer_item = get_object_or_404(OfferItemWoReceiver, id=self.box_id) context['box_description'] = html_box_content(offer_item, self.user) if self.is_basket: context['is_basket'] = "yes" context['is_select_view'] = EMPTY_STRING context['is_basket_view'] = 'active' customer = Customer.objects.filter( user_id=self.user.id, may_order=True).order_by('?').first() if customer is None: raise Http404 translation.activate(customer.language) customer_invoice = CustomerInvoice.objects.filter( permanence_id=self.permanence.id, customer_id=customer.id ).order_by('?').first() if customer_invoice is None: raise Http404 if customer_invoice.delivery is not None: status = customer_invoice.delivery.status else: status = customer_invoice.status basket_message = get_html_basket_message( customer, self.permanence, status ) html = customer_invoice.get_html_my_order_confirmation( permanence=self.permanence, is_basket=True, basket_message=basket_message ) context['span_btn_confirm_order'] = html['#span_btn_confirm_order'] else: context['is_basket'] = EMPTY_STRING context['is_select_view'] = 'active' context['is_basket_view'] = EMPTY_STRING context['is_like'] = "yes" if self.is_like else EMPTY_STRING context['communication'] = self.communication context['q'] = self.q context['may_order'] = self.may_order context['display_anonymous_order_form'] = REPANIER_SETTINGS_DISPLAY_ANONYMOUS_ORDER_FORM return context
def get_context_data(self, **kwargs): from repanier.apps import ( REPANIER_SETTINGS_DISPLAY_ANONYMOUS_ORDER_FORM, REPANIER_SETTINGS_CONFIG, REPANIER_SETTINGS_NOTIFICATION, ) context = super(OrderView, self).get_context_data(**kwargs) context["first_page"] = self.first_page context["permanence"] = self.permanence context["permanence_id"] = self.permanence.id context["all_dates"] = self.all_dates context["date_id"] = self.date_id context["date_Selected"] = self.date_selected context[ "notification"] = REPANIER_SETTINGS_NOTIFICATION.get_notification_display( ) if self.first_page: if settings.REPANIER_SETTINGS_SHOW_PRODUCER_ON_ORDER_FORM: producer_set = Producer.objects.filter( permanence=self.permanence.id).only( "id", "short_profile_name") else: producer_set = None context["producer_set"] = producer_set if self.producer_id == "all": department_set = (LUT_DepartmentForCustomer.objects.filter( offeritem__permanence_id=self.permanence.id, offeritem__is_active=True, offeritem__is_box=False, ).order_by("tree_id", "lft").distinct("id", "tree_id", "lft")) else: department_set = (LUT_DepartmentForCustomer.objects.filter( offeritem__producer_id=self.producer_id, offeritem__permanence_id=self.permanence.id, offeritem__is_active=True, offeritem__is_box=False, ).order_by("tree_id", "lft").distinct("id", "tree_id", "lft")) context["department_set"] = department_set context["box_set"] = OfferItemWoReceiver.objects.filter( permanence_id=self.permanence.id, is_box=True, is_active=True, may_order=True, translations__language_code=translation.get_language(), ).order_by("customer_unit_price", "unit_deposit", "translations__long_name") context["staff_order"] = Staff.get_or_create_order_responsible() if self.is_anonymous: context[ "how_to_register"] = REPANIER_SETTINGS_CONFIG.safe_translation_getter( "how_to_register", any_language=True, default=EMPTY_STRING) else: context["how_to_register"] = EMPTY_STRING # use of str() to avoid "12 345" when rendering the template context["producer_id"] = str(self.producer_id) # use of str() to avoid "12 345" when rendering the template context["department_id"] = str(self.department_id) context["box_id"] = str(self.box_id) context["is_box"] = "yes" if self.is_box else EMPTY_STRING if self.is_box: offer_item = get_object_or_404(OfferItemWoReceiver, id=self.box_id) context["box_description"] = html_box_content( offer_item, self.user) if self.is_basket: context["is_basket"] = "yes" context["is_select_view"] = EMPTY_STRING context["is_basket_view"] = "active" customer = (Customer.objects.filter( user_id=self.user.id, may_order=True).order_by("?").first()) if customer is None: raise Http404 translation.activate(customer.language) customer_invoice = (CustomerInvoice.objects.filter( permanence_id=self.permanence.id, customer_id=customer.id).order_by("?").first()) if customer_invoice is None: customer_invoice = CustomerInvoice.objects.create( permanence_id=self.permanence.id, customer_id=customer.id, status=self.permanence.status, customer_charged_id=customer.id, ) customer_invoice.set_order_delivery(delivery=None) customer_invoice.calculate_order_price() customer_invoice.save() if customer_invoice.delivery is not None: status = customer_invoice.delivery.status else: status = customer_invoice.status basket_message = get_html_basket_message(customer, self.permanence, status) html = customer_invoice.get_html_my_order_confirmation( permanence=self.permanence, is_basket=True, basket_message=basket_message, ) context["span_btn_confirm_order"] = html["#span_btn_confirm_order"] else: context["is_basket"] = EMPTY_STRING context["is_select_view"] = "active" context["is_basket_view"] = EMPTY_STRING context["is_like"] = "yes" if self.is_like else EMPTY_STRING context["communication"] = self.communication context["q"] = self.q context["may_order"] = self.may_order context[ "display_anonymous_order_form"] = REPANIER_SETTINGS_DISPLAY_ANONYMOUS_ORDER_FORM return context
def open_and_send_offer(self, request, queryset): if 'cancel' in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = queryset.first() if permanence.status not in [PERMANENCE_PLANNED, PERMANENCE_PRE_OPEN]: user_message = _("The status of %(permanence)s prohibit you to perform this action.") % { 'permanence': permanence} user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return pre_open = (permanence.status == PERMANENCE_PLANNED) and Producer.objects.filter( permanence__id=permanence.id, is_active=True, producer_pre_opening=True ).order_by('?').exists() if pre_open: template_offer_mail = [] template_cancel_order_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) with switch_language(repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.offer_producer_mail) staff = Staff.get_or_create_order_responsible() with switch_language(permanence, language_code): offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING ) context = TemplateContext({ 'name': _('Long name'), 'long_profile_name': _('Long name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(_("Offers"))), 'offer_description': mark_safe(offer_description), 'offer_link': mark_safe("<a href=\"#\">{}</a>".format(_("Offers"))), 'signature': staff.get_html_signature, }) template_offer_mail.append(language_code) template_offer_mail.append(template.render(context)) translation.activate(cur_language) email_will_be_sent, email_will_be_sent_to = send_email_to_who(True) else: template_offer_mail = [] template_cancel_order_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) with switch_language(repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.offer_customer_mail) staff = Staff.get_or_create_order_responsible() with switch_language(permanence, language_code): offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING ) offer_producer = ', '.join([p.short_profile_name for p in permanence.producers.all()]) qs = Product.objects.filter( producer=permanence.producers.first(), is_into_offer=True, order_unit__lt=PRODUCT_ORDER_UNIT_DEPOSIT # Don't display technical products. ).order_by( "translations__long_name" )[:5] offer_detail = "<ul>{}</ul>".format("".join("<li>{}, {}</li>".format( p.get_long_name(), p.producer.short_profile_name ) for p in qs ), ) context = TemplateContext({ 'offer_description': mark_safe(offer_description), 'offer_detail': offer_detail, 'offer_recent_detail': offer_detail, 'offer_producer': offer_producer, 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'signature': staff.get_html_signature, }) template_offer_mail.append(language_code) template_offer_mail.append(template.render(context)) if settings.REPANIER_SETTINGS_CUSTOMER_MUST_CONFIRM_ORDER: context = TemplateContext({ 'name': _('Long name'), 'long_basket_name': _('Long name'), 'basket_name': _('Short name'), 'short_basket_name': _('Short name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'signature': staff.get_html_signature, }) template_cancel_order_mail.append(language_code) template_cancel_order_mail.append(template.render(context)) translation.activate(cur_language) email_will_be_sent, email_will_be_sent_to = send_email_to_who() if 'apply' in request.POST or 'apply-wo-mail' in request.POST: form = OpenAndSendOfferForm(request.POST) if form.is_valid(): do_not_send_any_mail = 'apply-wo-mail' in request.POST if pre_open: permanence_already_pre_opened = Permanence.objects.filter( status__in=[PERMANENCE_WAIT_FOR_PRE_OPEN, PERMANENCE_PRE_OPEN] ).order_by("-is_updated_on").only("id").first() if permanence_already_pre_opened is not None: user_message = _("A maximum of one permanence may be pre opened.") user_message_level = messages.ERROR else: # pre_open_order(permanence.id) t = threading.Thread(target=pre_open_order, args=(permanence.id,)) t.start() user_message = _("The offers are being generated.") user_message_level = messages.INFO else: # open_order(permanence.id, do_not_send_any_mail) t = threading.Thread(target=open_order, args=(permanence.id, do_not_send_any_mail)) t.start() user_message = _("The offers are being generated.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(request.get_full_path()) else: form = OpenAndSendOfferForm( initial={ 'template_offer_customer_mail': mark_safe( "<br>==============<br>".join(template_offer_mail)), 'template_cancel_order_customer_mail': mark_safe( "<br>==============<br>".join(template_cancel_order_mail)), } ) return render( request, 'repanier/confirm_admin_open_and_send_offer.html', { 'sub_title': _("Please, confirm the action : open and send offers"), 'action_checkbox_name': admin.ACTION_CHECKBOX_NAME, 'action': 'open_and_send_offer', 'permanence': permanence, 'pre_open': pre_open, 'form': form, 'email_will_be_sent': email_will_be_sent, 'email_will_be_sent_to': email_will_be_sent_to })
def close_and_send_order(self, request, queryset): if 'cancel' in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = queryset.first() if permanence.status not in [PERMANENCE_OPENED, PERMANENCE_CLOSED]: user_message = _("The status of %(permanence)s prohibit you to perform this action.") % { 'permanence': permanence} user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return only_deliveries = permanence.with_delivery_point if 'apply' in request.POST: all_deliveries = True if request.POST.get("all-deliveries", False) else False deliveries_to_be_send = request.POST.getlist("deliveries", []) all_producers = True if request.POST.get("all-producers", False) else False producers_to_be_send = request.POST.getlist("producers", []) if only_deliveries: if not all_deliveries and len(deliveries_to_be_send) == 0: user_message = _("You must select at least one delivery point.") user_message_level = messages.WARNING self.message_user(request, user_message, user_message_level) return else: if not all_producers and len(producers_to_be_send) == 0: user_message = _("You must select at least one producer.") user_message_level = messages.WARNING self.message_user(request, user_message, user_message_level) return if not all_producers and settings.REPANIER_SETTINGS_CUSTOMER_MUST_CONFIRM_ORDER: user_message = _("You must select all producers because the customers must confirm orders.") user_message_level = messages.WARNING self.message_user(request, user_message, user_message_level) return everything = all_producers or all_deliveries # close_and_send_order(permanence.id, everything, producers_to_be_send, deliveries_to_be_send) t = threading.Thread(target=close_and_send_order, args=(permanence.id, everything, producers_to_be_send, deliveries_to_be_send)) t.start() user_message = _("The orders are being send.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return template_order_customer_mail = [] template_order_producer_mail = [] template_order_staff_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.order_customer_mail) staff = Staff.get_or_create_order_responsible() customer_last_balance = \ _('The balance of your account as of %(date)s is %(balance)s.') % { 'date': timezone.now().strftime(settings.DJANGO_SETTINGS_DATE), 'balance': RepanierMoney(123.45) } customer_on_hold_movement = \ _( 'This balance does not take account of any unrecognized payments %(bank)s and any unbilled order %(other_order)s.') \ % { 'bank': RepanierMoney(123.45), 'other_order': RepanierMoney(123.45) } bank_account_number = repanier.apps.REPANIER_SETTINGS_BANK_ACCOUNT if bank_account_number is not None: group_name = repanier.apps.REPANIER_SETTINGS_GROUP_NAME if permanence.short_name: communication = "{} ({})".format(_('Short name'), permanence.short_name) else: communication = _('Short name') customer_payment_needed = "<font color=\"#bd0926\">{}</font>".format( _( 'Please pay %(payment)s to the bank account %(name)s %(number)s with communication %(communication)s.') % { 'payment': RepanierMoney(123.45), 'name': group_name, 'number': bank_account_number, 'communication': communication } ) else: customer_payment_needed = EMPTY_STRING context = TemplateContext({ 'name': _('Long name'), 'long_basket_name': _('Long name'), 'basket_name': _('Short name'), 'short_basket_name': _('Short name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'last_balance': mark_safe("<a href=\"#\">{}</a>".format(customer_last_balance)), 'order_amount': RepanierMoney(123.45), 'on_hold_movement': mark_safe(customer_on_hold_movement), 'payment_needed': mark_safe(customer_payment_needed), 'delivery_point': _('Delivery point').upper(), 'signature': staff.get_html_signature, }) template_order_customer_mail.append(language_code) template_order_customer_mail.append(template.render(context)) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.order_producer_mail) context = TemplateContext({ 'name': _('Long name'), 'long_profile_name': _('Long name'), 'order_empty': False, 'duplicate': True, 'permanence_link': format_html("<a href=\"#\">{}</a>", permanence), 'signature': staff.get_html_signature, }) template_order_producer_mail.append(language_code) template_order_producer_mail.append(template.render(context)) board_composition, board_composition_and_description = get_board_composition(permanence.id) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.order_staff_mail) context = TemplateContext({ 'permanence_link': format_html("<a href=\"#\">{}</a>", permanence), 'board_composition': mark_safe(board_composition), 'board_composition_and_description': mark_safe(board_composition_and_description), 'signature': staff.get_html_signature, }) template_order_staff_mail.append(language_code) template_order_staff_mail.append(template.render(context)) translation.activate(cur_language) order_customer_email_will_be_sent, order_customer_email_will_be_sent_to = send_email_to_who() order_producer_email_will_be_sent, order_producer_email_will_be_sent_to = send_email_to_who() order_board_email_will_be_sent, order_board_email_will_be_sent_to = send_email_to_who( repanier.apps.REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD, board=True ) form = CloseAndSendOrderForm( initial={ 'template_order_customer_mail': mark_safe( "<br>==============<br>".join(template_order_customer_mail)), 'template_order_producer_mail': mark_safe( "<br>==============<br>".join(template_order_producer_mail)), 'template_order_staff_mail': mark_safe("<br>==============<br>".join(template_order_staff_mail)), } ) if only_deliveries: # /!\ If one delivery point has been closed, I may not close anymore by producer producers = Producer.objects.none() deliveries = DeliveryBoard.objects.filter( permanence_id=permanence.id, status__in=[PERMANENCE_OPENED, PERMANENCE_CLOSED] ) else: producers = Producer.objects.filter( producerinvoice__permanence_id=permanence.id, producerinvoice__status__in=[PERMANENCE_OPENED, PERMANENCE_CLOSED] ) deliveries = DeliveryBoard.objects.none() return render( request, 'repanier/confirm_admin_send_order.html', { 'sub_title': _("Please, confirm the action : send orders"), 'action_checkbox_name': admin.ACTION_CHECKBOX_NAME, 'action': 'close_and_send_order', 'permanence': permanence, 'only_deliveries': only_deliveries, 'deliveries': deliveries, 'producers': producers, 'form': form, 'order_customer_email_will_be_sent': order_customer_email_will_be_sent, 'order_customer_email_will_be_sent_to': order_customer_email_will_be_sent_to, 'order_producer_email_will_be_sent': order_producer_email_will_be_sent, 'order_producer_email_will_be_sent_to': order_producer_email_will_be_sent_to, 'order_board_email_will_be_sent': order_board_email_will_be_sent, 'order_board_email_will_be_sent_to': order_board_email_will_be_sent_to })
def send_pre_open_order(permanence_id): from repanier.apps import REPANIER_SETTINGS_GROUP_NAME, REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG offer_producer_mail = config.safe_translation_getter( 'offer_producer_mail', any_language=True, default=EMPTY_STRING) order_responsible = Staff.get_or_create_order_responsible() offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING) offer_producer_mail_subject = "{} - {}".format( REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(offer_producer_mail) producer_set = Producer.objects.filter( permanence=permanence_id, producer_pre_opening=True, language=language_code).order_by('?') for producer in producer_set: long_profile_name = producer.long_profile_name \ if producer.long_profile_name is not None else producer.short_profile_name context = TemplateContext({ 'name': long_profile_name, 'long_profile_name': long_profile_name, 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('pre_order_uuid_view', args=(producer.offer_uuid, )), _("Offers"))), 'offer_description': mark_safe(offer_description), 'offer_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('pre_order_uuid_view', args=(producer.offer_uuid, )), _("Offers"))), 'signature': order_responsible.get_html_signature }) html_body = template.render(context) to_email = [] if producer.email: to_email.append(producer.email) if producer.email2: to_email.append(producer.email2) if producer.email3: to_email.append(producer.email3) to_email = list( set(to_email + order_responsible.get_to_email + Staff.get_to_order_copy())) email = RepanierEmail( subject=offer_producer_mail_subject, html_body=html_body, from_email=order_responsible.get_from_email, reply_to=order_responsible.get_reply_to_email, to=to_email) email.send_email() send_sms(sms_nr=producer.phone1, sms_msg="{} : {} - {}".format( REPANIER_SETTINGS_GROUP_NAME, permanence, _("Pre-opening of orders"))) translation.activate(cur_language)
def send_open_order(permanence_id): from repanier.apps import REPANIER_SETTINGS_GROUP_NAME, REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG order_responsible = Staff.get_or_create_order_responsible() to_email = [] for customer in Customer.objects.filter( represent_this_buyinggroup=False, may_order=True, language=language_code).order_by('?'): to_email.append(customer.user.email) if customer.email2: to_email.append(customer.email2) offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING) offer_customer_mail = config.safe_translation_getter( 'offer_customer_mail', any_language=True, default=EMPTY_STRING) offer_customer_mail_subject = "{} - {}".format( REPANIER_SETTINGS_GROUP_NAME, permanence) offer_producer = ', '.join( [p.short_profile_name for p in permanence.producers.all()]) qs = OfferItemWoReceiver.objects.filter( permanence_id=permanence_id, is_active=True, order_unit__lt= PRODUCT_ORDER_UNIT_DEPOSIT, # Don't display technical products. translations__language_code=language_code).order_by( "translations__order_sort_order") offer_detail = "<ul>{}</ul>".format( "".join("<li>{}, {}, {}</li>".format( o.get_long_name(), o.producer.short_profile_name, o.email_offer_price_with_vat, ) for o in qs), ) template = Template(offer_customer_mail) context = TemplateContext({ 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id, )), permanence)), 'offer_description': mark_safe(offer_description), 'offer_detail': mark_safe(offer_detail), 'offer_recent_detail': mark_safe(permanence.get_new_products), 'offer_producer': offer_producer, 'signature': order_responsible.get_html_signature }) html_body = template.render(context) to_email = list( set(to_email + order_responsible.get_to_email + Staff.get_to_order_copy())) email = RepanierEmail(subject=offer_customer_mail_subject, html_body=html_body, from_email=order_responsible.get_from_email, reply_to=order_responsible.get_reply_to_email, to=to_email, show_customer_may_unsubscribe=True) email.send_email() translation.activate(cur_language)
def send_invoices(self, request, permanence_qs): if 'cancel' in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = permanence_qs.first() if permanence.status != PERMANENCE_INVOICED: user_message = _("The status of %(permanence)s prohibit you to perform this action.") % { 'permanence': permanence} user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.invoice_customer_mail) invoice_description = permanence.safe_translation_getter( 'invoice_description', any_language=True, default=EMPTY_STRING ) staff = Staff.get_or_create_invoice_responsible() # TODO : Align on tools.payment_message customer_order_amount = \ _('The amount of your order is %(amount)s.') % { 'amount': RepanierMoney(123.45) } customer_last_balance = \ _('The balance of your account as of %(date)s is %(balance)s.') % { 'date': timezone.now().strftime(settings.DJANGO_SETTINGS_DATE), 'balance': RepanierMoney(123.45) } customer_payment_needed = "{} {} {} ({}) {} \"{}\".".format( _('Please pay'), RepanierMoney(123.45), _('to the bank account number'), repanier.apps.REPANIER_SETTINGS_BANK_ACCOUNT, _('with communication'), _('Short name')) context = TemplateContext({ 'name': _('Long name'), 'long_basket_name': _('Long name'), 'basket_name': _('Short name'), 'short_basket_name': _('Short name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'last_balance_link': mark_safe("<a href=\"#\">{}</a>".format(customer_last_balance)), 'last_balance': customer_last_balance, 'order_amount': mark_safe(customer_order_amount), 'payment_needed': mark_safe(customer_payment_needed), 'invoice_description': mark_safe(invoice_description), 'signature': staff.get_html_signature, }) template_invoice_customer_mail = template.render(context) invoice_customer_email_will_be_sent, invoice_customer_email_will_be_sent_to = send_email_to_who( repanier.apps.REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER ) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.invoice_producer_mail) context = TemplateContext({ 'name': _('Long name'), 'long_profile_name': _('Long name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'signature': staff.get_html_signature, }) template_invoice_producer_mail = template.render(context) invoice_producer_email_will_be_sent, invoice_producer_email_will_be_sent_to = send_email_to_who( repanier.apps.REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER ) if 'apply' in request.POST: form = InvoiceOrderForm(request.POST) if form.is_valid(): t = threading.Thread(target=email_invoice.send_invoice, args=(permanence.id,)) t.start() user_message = _("Emails containing the invoices will be send to the customers and the producers.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(request.get_full_path()) else: form = InvoiceOrderForm( initial={ 'template_invoice_customer_mail': mark_safe(template_invoice_customer_mail), 'template_invoice_producer_mail': mark_safe(template_invoice_producer_mail), } ) return render( request, 'repanier/confirm_admin_send_invoice.html', { 'sub_title': _("Please, confirm the action : send invoices"), 'action_checkbox_name': admin.ACTION_CHECKBOX_NAME, 'action': 'send_invoices', 'permanence': permanence, 'form': form, 'invoice_customer_email_will_be_sent': invoice_customer_email_will_be_sent, 'invoice_customer_email_will_be_sent_to': invoice_customer_email_will_be_sent_to, 'invoice_producer_email_will_be_sent': invoice_producer_email_will_be_sent, 'invoice_producer_email_will_be_sent_to': invoice_producer_email_will_be_sent_to })
def open_order(self, request, permanence_id, permanence=None): if "apply" in request.POST or "apply-wo-mail" in request.POST: send_mail = not ("apply-wo-mail" in request.POST) # open_order(permanence.id, send_mail) t = threading.Thread(target=open_order, args=(permanence.id, send_mail)) t.start() user_message = _("The offers are being generated.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(self.get_redirect_to_change_list_url()) template_offer_mail = [] template_cancel_order_mail = [] email_will_be_sent, email_will_be_sent_to = RepanierEmail.send_email_to_who( ) if email_will_be_sent: cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) order_responsible = Staff.get_or_create_order_responsible() with switch_language(repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG. offer_customer_mail) with switch_language(permanence, language_code): offer_description = permanence.safe_translation_getter( "offer_description", any_language=True, default=EMPTY_STRING) offer_producer = ", ".join( [p.short_profile_name for p in permanence.producers.all()]) qs = Product.objects.filter( producer=permanence.producers.first(), is_into_offer=True, order_unit__lt= PRODUCT_ORDER_UNIT_DEPOSIT, # Don't display technical products. ).order_by("translations__long_name")[:5] offer_detail = "<ul>{}</ul>".format( "".join("<li>{}, {}</li>".format( p.get_long_name(), p.producer.short_profile_name) for p in qs)) context = TemplateContext({ "offer_description": mark_safe(offer_description), "offer_detail": offer_detail, "offer_recent_detail": offer_detail, "offer_producer": offer_producer, "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "signature": order_responsible["html_signature"], }) template_offer_mail.append(language_code) template_offer_mail.append(template.render(context)) if settings.REPANIER_SETTINGS_CUSTOMER_MUST_CONFIRM_ORDER: with switch_language( repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG. cancel_order_customer_mail) context = TemplateContext({ "name": _("Long name"), "long_basket_name": _("Long name"), "basket_name": _("Short name"), "short_basket_name": _("Short name"), "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "signature": order_responsible["html_signature"], }) template_cancel_order_mail.append(language_code) template_cancel_order_mail.append(template.render(context)) translation.activate(cur_language) form = OpenAndSendOfferForm( initial={ "template_offer_customer_mail": mark_safe("<br>==============<br>".join(template_offer_mail)), "template_cancel_order_customer_mail": mark_safe("<br>==============<br>".join( template_cancel_order_mail)), }) template_name = get_repanier_template_name( "admin/confirm_open_order.html") return render( request, template_name, { **self.admin_site.each_context(request), "action_checkbox_name": admin.ACTION_CHECKBOX_NAME, "action": "open_order", "permanence": permanence, "form": form, "email_will_be_sent": email_will_be_sent, "email_will_be_sent_to": email_will_be_sent_to, }, )
def close_and_send_order(self, request, queryset): if 'cancel' in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = queryset.first() if permanence.status not in [PERMANENCE_OPENED, PERMANENCE_CLOSED]: user_message = _("The status of %(permanence)s prohibit you to perform this action.") % { 'permanence': permanence} user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return if 'apply' in request.POST: all_deliveries = True if request.POST.get("all-deliveries", True) else False deliveries_to_be_send = request.POST.getlist("deliveries", []) logger.debug("all_deliveries : {}".format(request.POST.get("all-deliveries"))) logger.debug("all_deliveries : {}".format(all_deliveries)) logger.debug("deliveries_to_be_send : {}".format(request.POST.getlist("deliveries", []))) if permanence.with_delivery_point and not all_deliveries and len(deliveries_to_be_send) == 0: user_message = _("You must select at least one delivery point.") user_message_level = messages.WARNING self.message_user(request, user_message, user_message_level) return # close_and_send_order(permanence.id, all_deliveries, deliveries_to_be_send) t = threading.Thread(target=close_and_send_order, args=(permanence.id, all_deliveries, deliveries_to_be_send)) t.start() user_message = _("The orders are being send.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return template_order_customer_mail = [] template_order_producer_mail = [] template_order_staff_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.order_customer_mail) staff = Staff.get_or_create_order_responsible() customer_last_balance = \ _('The balance of your account as of %(date)s is %(balance)s.') % { 'date': timezone.now().strftime(settings.DJANGO_SETTINGS_DATE), 'balance': RepanierMoney(123.45) } customer_on_hold_movement = \ _( 'This balance does not take account of any unrecognized payments %(bank)s and any unbilled order %(other_order)s.') \ % { 'bank': RepanierMoney(123.45), 'other_order': RepanierMoney(123.45) } bank_account_number = repanier.apps.REPANIER_SETTINGS_BANK_ACCOUNT if bank_account_number is not None: group_name = settings.REPANIER_SETTINGS_GROUP_NAME if permanence.short_name: communication = "{} ({})".format(_('Short name'), permanence.short_name) else: communication = _('Short name') customer_payment_needed = "<font color=\"#bd0926\">{}</font>".format( _( 'Please pay a provision of %(payment)s to the bank account %(name)s %(number)s with communication %(communication)s.') % { 'payment': RepanierMoney(123.45), 'name': group_name, 'number': bank_account_number, 'communication': communication } ) else: customer_payment_needed = EMPTY_STRING context = TemplateContext({ 'name': _('Long name'), 'long_basket_name': _('Long name'), 'basket_name': _('Short name'), 'short_basket_name': _('Short name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'last_balance': mark_safe("<a href=\"#\">{}</a>".format(customer_last_balance)), 'order_amount': RepanierMoney(123.45), 'on_hold_movement': mark_safe(customer_on_hold_movement), 'payment_needed': mark_safe(customer_payment_needed), 'delivery_point': _('Delivery point').upper(), 'signature': staff.get_html_signature, }) template_order_customer_mail.append(language_code) template_order_customer_mail.append(template.render(context)) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.order_producer_mail) context = TemplateContext({ 'name': _('Long name'), 'long_profile_name': _('Long name'), 'order_empty': False, 'duplicate': True, 'permanence_link': format_html("<a href=\"#\">{}</a>", permanence), 'signature': staff.get_html_signature, }) template_order_producer_mail.append(language_code) template_order_producer_mail.append(template.render(context)) board_composition, board_composition_and_description = get_board_composition(permanence.id) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.order_staff_mail) context = TemplateContext({ 'permanence_link': format_html("<a href=\"#\">{}</a>", permanence), 'board_composition': mark_safe(board_composition), 'board_composition_and_description': mark_safe(board_composition_and_description), 'signature': staff.get_html_signature, }) template_order_staff_mail.append(language_code) template_order_staff_mail.append(template.render(context)) translation.activate(cur_language) order_customer_email_will_be_sent, order_customer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=True ) order_producer_email_will_be_sent, order_producer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=True ) order_board_email_will_be_sent, order_board_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps.REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD, board=True ) form = CloseAndSendOrderForm( initial={ 'template_order_customer_mail': mark_safe( "<br>==============<br>".join(template_order_customer_mail)), 'template_order_producer_mail': mark_safe( "<br>==============<br>".join(template_order_producer_mail)), 'template_order_staff_mail': mark_safe("<br>==============<br>".join(template_order_staff_mail)), } ) if permanence.with_delivery_point: deliveries = DeliveryBoard.objects.filter( permanence_id=permanence.id, status__in=[PERMANENCE_OPENED, PERMANENCE_CLOSED] ) else: deliveries = DeliveryBoard.objects.none() template_name = get_repanier_template_name("confirm_admin_send_order.html") return render( request, template_name, { 'sub_title': _("Please, confirm the action : send orders"), 'action_checkbox_name': admin.ACTION_CHECKBOX_NAME, 'action': 'close_and_send_order', 'permanence': permanence, 'with_delivery_point': permanence.with_delivery_point, 'deliveries': deliveries, 'form': form, 'order_customer_email_will_be_sent': order_customer_email_will_be_sent, 'order_customer_email_will_be_sent_to': order_customer_email_will_be_sent_to, 'order_producer_email_will_be_sent': order_producer_email_will_be_sent, 'order_producer_email_will_be_sent_to': order_producer_email_will_be_sent_to, 'order_board_email_will_be_sent': order_board_email_will_be_sent, 'order_board_email_will_be_sent_to': order_board_email_will_be_sent_to })
def send_invoice(permanence_id): from repanier.apps import REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER, \ REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER, \ REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG invoice_responsible = Staff.get_or_create_invoice_responsible() if REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER: # To the producer we speak of "payment". # This is the detail of the payment to the producer, i.e. received products for producer in Producer.objects.filter( permanence_id=permanence.id, language=language_code ).order_by('?'): to_email = [] if producer.email: to_email.append(producer.email) if producer.email2: to_email.append(producer.email2) if producer.email3: to_email.append(producer.email3) if to_email: to_email = list(set(to_email + invoice_responsible.get_to_email)) long_profile_name = producer.long_profile_name \ if producer.long_profile_name is not None else producer.short_profile_name if Purchase.objects.filter( permanence_id=permanence.id, producer_id=producer.id ).order_by('?').exists(): invoice_producer_mail = config.safe_translation_getter( 'invoice_producer_mail', any_language=True, default=EMPTY_STRING ) invoice_producer_mail_subject = "{} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(invoice_producer_mail) context = TemplateContext({ 'name': long_profile_name, 'long_profile_name': long_profile_name, 'permanence_link': mark_safe( "<a href=\"https://{}{}\">{}</a>".format(settings.ALLOWED_HOSTS[0], reverse('producer_invoice_uuid_view', args=(0, producer.uuid)), permanence)), 'signature': invoice_responsible.get_html_signature }) html_body = template.render(context) email = RepanierEmail( subject=invoice_producer_mail_subject, html_body=html_body, to=to_email ) email.send_email() if REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER: # To the customer we speak of "invoice". # This is the detail of the invoice, i.e. sold products invoice_description = permanence.safe_translation_getter( 'invoice_description', any_language=True, default=EMPTY_STRING ) for customer in Customer.objects.filter( customerinvoice__permanence_id=permanence.id, customerinvoice__customer_charged_id=F('customer_id'), represent_this_buyinggroup=False, language=language_code ).order_by('?'): long_basket_name = customer.long_basket_name if customer.long_basket_name is not None else customer.short_basket_name if Purchase.objects.filter( permanence_id=permanence.id, customer_invoice__customer_charged_id=customer.id ).order_by('?').exists(): to_email = [customer.user.email] if customer.email2: to_email.append(customer.email2) to_email = list(set(to_email + invoice_responsible.get_to_email)) invoice_customer_mail = config.safe_translation_getter( 'invoice_customer_mail', any_language=True, default=EMPTY_STRING ) invoice_customer_mail_subject = "{} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence) customer_last_balance, _, customer_payment_needed, customer_order_amount = payment_message( customer, permanence) template = Template(invoice_customer_mail) context = TemplateContext({ 'name': long_basket_name, 'long_basket_name': long_basket_name, 'basket_name': customer.short_basket_name, 'short_basket_name': customer.short_basket_name, 'permanence_link': mark_safe( "<a href=\"https://{}{}\">{}</a>".format(settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)), 'last_balance_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0,)), customer_last_balance)), 'last_balance': mark_safe(customer_last_balance), 'order_amount': mark_safe(customer_order_amount), 'payment_needed': mark_safe(customer_payment_needed), 'invoice_description': mark_safe(invoice_description), 'signature': invoice_responsible.get_html_signature }) html_body = template.render(context) email = RepanierEmail( subject=invoice_customer_mail_subject, html_body=html_body, to=to_email, show_customer_may_unsubscribe=True ) email.send_email() translation.activate(cur_language)
def send_pre_open_order(permanence_id): from repanier.apps import REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG offer_producer_mail = config.safe_translation_getter( 'offer_producer_mail', any_language=True, default=EMPTY_STRING ) order_responsible = Staff.get_or_create_order_responsible() offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING ) offer_producer_mail_subject = "{} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(offer_producer_mail) producer_set = Producer.objects.filter( permanence=permanence_id, producer_pre_opening=True, language=language_code ).order_by('?') for producer in producer_set: long_profile_name = producer.long_profile_name \ if producer.long_profile_name is not None else producer.short_profile_name context = TemplateContext({ 'name': long_profile_name, 'long_profile_name': long_profile_name, 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('pre_order_uuid_view', args=(producer.offer_uuid,)), _("Offers")) ), 'offer_description': mark_safe(offer_description), 'offer_link': mark_safe( "<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('pre_order_uuid_view', args=(producer.offer_uuid,)), _("Offers")) ), 'signature': order_responsible.get_html_signature }) html_body = template.render(context) to_email = [] if producer.email: to_email.append(producer.email) if producer.email2: to_email.append(producer.email2) if producer.email3: to_email.append(producer.email3) to_email = list(set(to_email + order_responsible.get_to_email)) email = RepanierEmail( subject=offer_producer_mail_subject, html_body=html_body, to=to_email ) email.send_email() send_sms( sms_nr=producer.get_phone1(), sms_msg="{} : {} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence, _("Pre-opening of orders"))) translation.activate(cur_language)
def send_invoices(self, request, permanence_id, permanence=None): if "apply" in request.POST: t = threading.Thread(target=email_invoice.send_invoice, args=(permanence_id, )) t.start() user_message = _("The invoices are being send.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(self.get_redirect_to_change_list_url()) template_invoice_customer_mail = [] template_invoice_producer_mail = [] invoice_customer_email_will_be_sent, invoice_customer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps. REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER) invoice_producer_email_will_be_sent, invoice_producer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps. REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER) if invoice_customer_email_will_be_sent or invoice_producer_email_will_be_sent: cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) invoice_responsible = Staff.get_or_create_invoice_responsible() if invoice_customer_email_will_be_sent: with switch_language( repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG. invoice_customer_mail) with switch_language(permanence, language_code): invoice_description = permanence.safe_translation_getter( "invoice_description", any_language=True, default=EMPTY_STRING, ) # TODO : Align on tools.payment_message customer_order_amount = _( "The amount of your order is %(amount)s.") % { "amount": RepanierMoney(123.45) } customer_last_balance = _( "The balance of your account as of %(date)s is %(balance)s." ) % { "date": timezone.now().strftime(settings.DJANGO_SETTINGS_DATE), "balance": RepanierMoney(123.45), } bank_account_number = repanier.apps.REPANIER_SETTINGS_BANK_ACCOUNT if bank_account_number is not None: group_name = settings.REPANIER_SETTINGS_GROUP_NAME if permanence.short_name: communication = "{} ({})".format( _("Short name"), permanence.short_name) else: communication = _("Short name") customer_payment_needed = '<font color="#bd0926">{}</font>'.format( _("Please pay a provision of %(payment)s to the bank account %(name)s %(number)s with communication %(communication)s." ) % { "payment": RepanierMoney(123.45), "name": group_name, "number": bank_account_number, "communication": communication, }) else: customer_payment_needed = EMPTY_STRING context = TemplateContext({ "name": _("Long name"), "long_basket_name": _("Long name"), "basket_name": _("Short name"), "short_basket_name": _("Short name"), "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "last_balance_link": mark_safe('<a href="#">{}</a>'.format( customer_last_balance)), "last_balance": customer_last_balance, "order_amount": mark_safe(customer_order_amount), "payment_needed": mark_safe(customer_payment_needed), "invoice_description": mark_safe(invoice_description), "signature": invoice_responsible["html_signature"], }) template_invoice_customer_mail.append(language_code) template_invoice_customer_mail.append( template.render(context)) if invoice_producer_email_will_be_sent: with switch_language( repanier.apps.REPANIER_SETTINGS_CONFIG, language_code): template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG. invoice_producer_mail) context = TemplateContext({ "name": _("Long name"), "long_profile_name": _("Long name"), "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "signature": invoice_responsible["html_signature"], }) template_invoice_producer_mail.append(language_code) template_invoice_producer_mail.append( template.render(context)) translation.activate(cur_language) form = InvoiceOrderForm( initial={ "template_invoice_customer_mail": mark_safe("<br>==============<br>".join( template_invoice_customer_mail)), "template_invoice_producer_mail": mark_safe("<br>==============<br>".join( template_invoice_producer_mail)), }) template_name = get_repanier_template_name( "admin/confirm_send_invoice.html") return render( request, template_name, { **self.admin_site.each_context(request), "action_checkbox_name": admin.ACTION_CHECKBOX_NAME, "action": "send_invoices", "permanence": permanence, "form": form, "invoice_customer_email_will_be_sent_to": invoice_customer_email_will_be_sent_to, "invoice_producer_email_will_be_sent_to": invoice_producer_email_will_be_sent_to, }, )
def send_open_order(permanence_id): from repanier.apps import REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG order_responsible = Staff.get_or_create_order_responsible() to_email = [] for customer in Customer.objects.filter( represent_this_buyinggroup=False, may_order=True, language=language_code ).order_by('?'): to_email.append(customer.user.email) if customer.email2: to_email.append(customer.email2) offer_description = permanence.safe_translation_getter( 'offer_description', any_language=True, default=EMPTY_STRING ) offer_customer_mail = config.safe_translation_getter( 'offer_customer_mail', any_language=True, default=EMPTY_STRING ) offer_customer_mail_subject = "{} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence) offer_producer = ', '.join([p.short_profile_name for p in permanence.producers.all()]) qs = OfferItemWoReceiver.objects.filter( permanence_id=permanence_id, is_active=True, order_unit__lt=PRODUCT_ORDER_UNIT_DEPOSIT, # Don't display technical products. translations__language_code=language_code ).order_by( "translations__order_sort_order" ) offer_detail = "<ul>{}</ul>".format("".join("<li>{}, {}, {}</li>".format( o.get_long_name(), o.producer.short_profile_name, o.email_offer_price_with_vat, ) for o in qs ), ) if permanence.picture: permanence_picture = format_html( """ <img alt="{0}" title="{0}" style="float: left; margin: 5px;" src="https:/{1}{2}{3}"/> """ , permanence.get_permanence_display(), settings.ALLOWED_HOSTS[0], settings.MEDIA_URL, permanence.picture, ) offer_description = "<hr/>{}<hr/>{}".format(permanence_picture, offer_description) template = Template(offer_customer_mail) context = TemplateContext({ 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)), 'offer_description': mark_safe(offer_description), 'offer_detail': mark_safe(offer_detail), 'offer_recent_detail': mark_safe(permanence.get_new_products), 'offer_producer': offer_producer, 'signature': order_responsible.get_html_signature }) html_body = template.render(context) to_email = list(set(to_email + order_responsible.get_to_email)) email = RepanierEmail( subject=offer_customer_mail_subject, html_body=html_body, to=to_email, show_customer_may_unsubscribe=True ) email.send_email() translation.activate(cur_language)
def get_context_data(self, **kwargs): from repanier.apps import REPANIER_SETTINGS_DISPLAY_ANONYMOUS_ORDER_FORM, REPANIER_SETTINGS_CONFIG, \ REPANIER_SETTINGS_NOTIFICATION context = super(OrderView, self).get_context_data(**kwargs) context['first_page'] = self.first_page context['permanence'] = self.permanence context['permanence_id'] = self.permanence.id context["all_dates"] = self.all_dates context["date_id"] = self.date_id context["date_Selected"] = self.date_selected context["notification"] = None if self.is_anonymous and \ not REPANIER_SETTINGS_NOTIFICATION.notification_is_public else \ REPANIER_SETTINGS_NOTIFICATION.safe_translation_getter('notification', any_language=True) if self.first_page: if settings.REPANIER_SETTINGS_SHOW_PRODUCER_ON_ORDER_FORM: producer_set = Producer.objects.filter( permanence=self.permanence.id).only( "id", "short_profile_name") else: producer_set = None context['producer_set'] = producer_set if self.producer_id == 'all': department_set = LUT_DepartmentForCustomer.objects.filter( offeritem__permanence_id=self.permanence.id, offeritem__is_active=True, offeritem__is_box=False) \ .order_by("tree_id", "lft") \ .distinct("id", "tree_id", "lft") else: department_set = LUT_DepartmentForCustomer.objects.filter( offeritem__producer_id=self.producer_id, offeritem__permanence_id=self.permanence.id, offeritem__is_active=True, offeritem__is_box=False) \ .order_by("tree_id", "lft") \ .distinct("id", "tree_id", "lft") context['department_set'] = department_set context['box_set'] = OfferItemWoReceiver.objects.filter( permanence_id=self.permanence.id, is_box=True, is_active=True, may_order=True, translations__language_code=translation.get_language( )).order_by( 'customer_unit_price', 'unit_deposit', 'translations__long_name', ) context['staff_order'] = Staff.get_or_create_order_responsible() if self.is_anonymous: context[ 'how_to_register'] = REPANIER_SETTINGS_CONFIG.safe_translation_getter( 'how_to_register', any_language=True, default=EMPTY_STRING) else: context['how_to_register'] = EMPTY_STRING # use of str() to avoid "12 345" when rendering the template context['producer_id'] = str(self.producer_id) # use of str() to avoid "12 345" when rendering the template context['department_id'] = str(self.department_id) context['box_id'] = str(self.box_id) context['is_box'] = "yes" if self.is_box else EMPTY_STRING if self.is_box: offer_item = get_object_or_404(OfferItemWoReceiver, id=self.box_id) context['box_description'] = html_box_content( offer_item, self.user) context['is_basket'] = "yes" if self.is_basket else EMPTY_STRING context['is_like'] = "yes" if self.is_like else EMPTY_STRING context['communication'] = self.communication context['q'] = self.q context['may_order'] = self.may_order context[ 'display_anonymous_order_form'] = REPANIER_SETTINGS_DISPLAY_ANONYMOUS_ORDER_FORM return context
def send_invoices(self, request, permanence_qs): if 'cancel' in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = permanence_qs.first() if permanence.status != PERMANENCE_INVOICED: user_message = _("The status of %(permanence)s prohibit you to perform this action.") % { 'permanence': permanence} user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.invoice_customer_mail) invoice_description = permanence.safe_translation_getter( 'invoice_description', any_language=True, default=EMPTY_STRING ) staff = Staff.get_or_create_invoice_responsible() # TODO : Align on tools.payment_message customer_order_amount = \ _('The amount of your order is %(amount)s.') % { 'amount': RepanierMoney(123.45) } customer_last_balance = \ _('The balance of your account as of %(date)s is %(balance)s.') % { 'date': timezone.now().strftime(settings.DJANGO_SETTINGS_DATE), 'balance': RepanierMoney(123.45) } bank_account_number = repanier.apps.REPANIER_SETTINGS_BANK_ACCOUNT if bank_account_number is not None: group_name = settings.REPANIER_SETTINGS_GROUP_NAME if permanence.short_name: communication = "{} ({})".format(_('Short name'), permanence.short_name) else: communication = _('Short name') customer_payment_needed = "<font color=\"#bd0926\">{}</font>".format( _( 'Please pay a provision of %(payment)s to the bank account %(name)s %(number)s with communication %(communication)s.') % { 'payment': RepanierMoney(123.45), 'name': group_name, 'number': bank_account_number, 'communication': communication } ) else: customer_payment_needed = EMPTY_STRING context = TemplateContext({ 'name': _('Long name'), 'long_basket_name': _('Long name'), 'basket_name': _('Short name'), 'short_basket_name': _('Short name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'last_balance_link': mark_safe("<a href=\"#\">{}</a>".format(customer_last_balance)), 'last_balance': customer_last_balance, 'order_amount': mark_safe(customer_order_amount), 'payment_needed': mark_safe(customer_payment_needed), 'invoice_description': mark_safe(invoice_description), 'signature': staff.get_html_signature, }) template_invoice_customer_mail = template.render(context) invoice_customer_email_will_be_sent, invoice_customer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps.REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER ) template = Template(repanier.apps.REPANIER_SETTINGS_CONFIG.invoice_producer_mail) context = TemplateContext({ 'name': _('Long name'), 'long_profile_name': _('Long name'), 'permanence_link': mark_safe("<a href=\"#\">{}</a>".format(permanence)), 'signature': staff.get_html_signature, }) template_invoice_producer_mail = template.render(context) invoice_producer_email_will_be_sent, invoice_producer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps.REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER ) if 'apply' in request.POST: form = InvoiceOrderForm(request.POST) if form.is_valid(): t = threading.Thread(target=email_invoice.send_invoice, args=(permanence.id,)) t.start() user_message = _("Emails containing the invoices will be send to the customers and the producers.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(request.get_full_path()) else: form = InvoiceOrderForm( initial={ 'template_invoice_customer_mail': mark_safe(template_invoice_customer_mail), 'template_invoice_producer_mail': mark_safe(template_invoice_producer_mail), } ) template_name = get_repanier_template_name( 'repanier/confirm_admin_send_invoice.html' ) return render( request, template_name, { 'sub_title': _("Please, confirm the action : send invoices"), 'action_checkbox_name': admin.ACTION_CHECKBOX_NAME, 'action': 'send_invoices', 'permanence': permanence, 'form': form, 'invoice_customer_email_will_be_sent': invoice_customer_email_will_be_sent, 'invoice_customer_email_will_be_sent_to': invoice_customer_email_will_be_sent_to, 'invoice_producer_email_will_be_sent': invoice_producer_email_will_be_sent, 'invoice_producer_email_will_be_sent_to': invoice_producer_email_will_be_sent_to })
def init_repanier(cls): from repanier.const import DECIMAL_ONE, PERMANENCE_NAME_PERMANENCE, CURRENCY_EUR from repanier.models.producer import Producer from repanier.models.bankaccount import BankAccount from repanier.models.staff import Staff from repanier.models.customer import Customer from repanier.models.lut import LUT_DepartmentForCustomer logger.debug("######## start of init_repanier") # Create the configuration record managed via the admin UI config = Configuration.objects.filter(id=DECIMAL_ONE).first() if config is not None: return config site = Site.objects.get_current() if site is not None: site.name = settings.REPANIER_SETTINGS_GROUP_NAME site.domain = settings.ALLOWED_HOSTS[0] site.save() config = Configuration.objects.create( group_name=settings.REPANIER_SETTINGS_GROUP_NAME, name=PERMANENCE_NAME_PERMANENCE, bank_account="BE99 9999 9999 9999", currency=CURRENCY_EUR, ) config.init_email() config.save() # Create firsts users Producer.get_or_create_group() customer_buyinggroup = Customer.get_or_create_group() very_first_customer = Customer.get_or_create_the_very_first_customer() BankAccount.open_account( customer_buyinggroup=customer_buyinggroup, very_first_customer=very_first_customer, ) very_first_customer = Customer.get_or_create_the_very_first_customer() coordinator = Staff.get_or_create_any_coordinator() Staff.get_or_create_order_responsible() Staff.get_or_create_invoice_responsible() # Create and publish first web page if not coordinator.is_webmaster: # This should not be the case... return from cms.models import StaticPlaceholder from cms.constants import X_FRAME_OPTIONS_DENY from cms import api page = api.create_page( title=_("Home"), soft_root=False, template=settings.CMS_TEMPLATE_HOME, language=settings.LANGUAGE_CODE, published=True, parent=None, xframe_options=X_FRAME_OPTIONS_DENY, in_navigation=True, ) try: # New in CMS 3.5 page.set_as_homepage() except: pass placeholder = page.placeholders.get(slot="home-hero") api.add_plugin( placeholder=placeholder, plugin_type="TextPlugin", language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_HERO, ) static_placeholder = StaticPlaceholder( code="footer", # site_id=1 ) static_placeholder.save() api.add_plugin( placeholder=static_placeholder.draft, plugin_type="TextPlugin", language=settings.LANGUAGE_CODE, body="hello world footer", ) static_placeholder.publish( request=None, language=settings.LANGUAGE_CODE, force=True ) api.publish_page( page=page, user=coordinator.customer_responsible.user, language=settings.LANGUAGE_CODE, ) if LUT_DepartmentForCustomer.objects.count() == 0: # Generate a template of LUT_DepartmentForCustomer parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Vegetable")) LUT_DepartmentForCustomer.objects.create( short_name=_("Basket of vegetables"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Salad"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Tomato"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Potato"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Green"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Cabbage"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Fruit")) LUT_DepartmentForCustomer.objects.create( short_name=_("Basket of fruits"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Apple"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Pear"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Plum"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Bakery")) LUT_DepartmentForCustomer.objects.create( short_name=_("Flour"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Bread"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Pastry"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Butchery")) LUT_DepartmentForCustomer.objects.create( short_name=_("Delicatessen"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Chicken"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Pork"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Beef"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Beef and pork"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Veal"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Lamb"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Grocery")) LUT_DepartmentForCustomer.objects.create( short_name=_("Takeaway"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Pasta"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Chocolate"), parent=parent ) LUT_DepartmentForCustomer.objects.create(short_name=_("Oil"), parent=parent) LUT_DepartmentForCustomer.objects.create(short_name=_("Egg"), parent=parent) LUT_DepartmentForCustomer.objects.create(short_name=_("Jam"), parent=parent) LUT_DepartmentForCustomer.objects.create( short_name=_("Cookie"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Creamery")) LUT_DepartmentForCustomer.objects.create( short_name=_("Dairy"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Cow cheese"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Goat cheese"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Sheep cheese"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Mixed cheese"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Icecream")) LUT_DepartmentForCustomer.objects.create( short_name=_("Cup of icecream"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Icecream per liter"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Icecream in frisco"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Icecream cake"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Sorbet")) LUT_DepartmentForCustomer.objects.create( short_name=_("Cup of sorbet"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Sorbet per liter"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Drink")) LUT_DepartmentForCustomer.objects.create( short_name=_("Juice"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Coffee"), parent=parent ) LUT_DepartmentForCustomer.objects.create(short_name=_("Tea"), parent=parent) LUT_DepartmentForCustomer.objects.create( short_name=_("Herbal tea"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Wine"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Aperitif"), parent=parent ) LUT_DepartmentForCustomer.objects.create( short_name=_("Liqueurs"), parent=parent ) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Hygiene")) parent = LUT_DepartmentForCustomer.objects.create(short_name=_("Deposit")) parent = LUT_DepartmentForCustomer.objects.create( short_name=_("Subscription") ) logger.debug("######## end of init_repanier") return config
def export_order_2_1_group(config, delivery_id, filename, permanence, order_responsible): delivery_board = DeliveryBoard.objects.filter(id=delivery_id).exclude( delivery_point__customer_responsible=None).order_by('?').first() if delivery_board is None: return from repanier.apps import REPANIER_SETTINGS_GROUP_NAME delivery_point = delivery_board.delivery_point customer_responsible = delivery_point.customer_responsible wb = generate_customer_xlsx(permanence=permanence, deliveries_id=[delivery_id], group=True)[0] if wb is not None: order_customer_mail = config.safe_translation_getter( 'order_customer_mail', any_language=True, default=EMPTY_STRING) order_customer_mail_subject = "{} - {}".format( REPANIER_SETTINGS_GROUP_NAME, permanence) long_basket_name = customer_responsible.long_basket_name or str( customer_responsible) template = Template(order_customer_mail) context = TemplateContext({ 'name': long_basket_name, 'long_basket_name': long_basket_name, # deprecated 'basket_name': str(customer_responsible), 'short_basket_name': str(customer_responsible), # deprecated 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id, )), permanence)), 'last_balance_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0, )), _("Group invoices"))), 'last_balance': EMPTY_STRING, 'order_amount': EMPTY_STRING, 'on_hold_movement': EMPTY_STRING, 'payment_needed': EMPTY_STRING, 'delivery_point': delivery_point, 'signature': order_responsible.get_html_signature }) html_body = template.render(context) to_email = [customer_responsible.user.email] if customer_responsible.email2: to_email.append(customer_responsible.email2) to_email = list( set(to_email + order_responsible.get_to_email + Staff.get_to_order_copy())) email = RepanierEmail(subject=order_customer_mail_subject, html_body=html_body, from_email=order_responsible.get_from_email, to=to_email, reply_to=order_responsible.get_reply_to) email.attach( filename, save_virtual_workbook(wb), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) email.send_email()
def email_order(permanence_id, everything=True, deliveries_id=()): from repanier.apps import REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD, REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG filename = "{}-{}.xlsx".format( _("Order"), permanence ) order_responsible = Staff.get_or_create_order_responsible() if len(deliveries_id) > 0: for delivery_id in deliveries_id: # Send a recap of the orders to the responsible export_order_2_1_group( config, delivery_id, filename, permanence, order_responsible ) if not everything: abstract_ws = None else: # Orders send to the preparation team, to the order_responsible wb, abstract_ws = generate_customer_xlsx(permanence=permanence, deliveries_id=deliveries_id) if wb is not None: # At least one order order_staff_mail = config.safe_translation_getter( 'order_staff_mail', any_language=True, default=EMPTY_STRING ) order_staff_mail_subject = "{} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence) board_composition, board_composition_and_description = get_board_composition(permanence.id) template = Template(order_staff_mail) context = TemplateContext({ 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)), 'board_composition': mark_safe(board_composition), 'board_composition_and_description': mark_safe(board_composition_and_description), 'signature': order_responsible.get_html_signature }) html_body = template.render(context) if REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD: to_email = [] for permanence_board in PermanenceBoard.objects.filter( permanence_id=permanence.id).order_by('?'): if permanence_board.customer: to_email.append(permanence_board.customer.user.email) to_email = list(set(to_email + order_responsible.get_to_email)) else: to_email = list(set(order_responsible.get_to_email)) email = RepanierEmail( subject=order_staff_mail_subject, html_body=html_body, to=to_email, ) email.attach(filename, save_virtual_workbook(wb), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet') email.send_email() # Orders send to our producers # producer_set = Producer.objects.filter( # permanence=permanence, # language=language_code, # ).order_by('?') # all_producers = permanence.contract.producers.all() if permanence.contract else permanence.producers.all() producer_set = Producer.objects.filter( permanence=permanence, language=language_code, ).order_by('?') for producer in producer_set: long_profile_name = producer.long_profile_name if producer.long_profile_name is not None else producer.short_profile_name wb = generate_producer_xlsx(permanence=permanence, producer=producer, wb=None) order_producer_mail = config.safe_translation_getter( 'order_producer_mail', any_language=True, default=EMPTY_STRING ) order_producer_mail_subject = "{} - {}".format(settings.REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(order_producer_mail) context = TemplateContext({ 'name': long_profile_name, 'long_profile_name': long_profile_name, 'order_empty': wb is None, 'duplicate': not (wb is None or producer.manage_replenishment), 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id,)), permanence)), 'signature': order_responsible.get_html_signature }) html_body = template.render(context) producer_invoice = ProducerInvoice.objects.filter( producer_id=producer.id, permanence_id=permanence.id ).order_by('?').first() to_email = [] if producer_invoice is not None \ and producer_invoice.get_total_price_with_tax() < producer.minimum_order_value: html_body = "{}<br><br>{}".format( order_producer_mail_subject, html_body ) order_producer_mail_subject = _( '⚠ Mail not send to our producer {} because the minimum order value has not been reached.').format( long_profile_name) else: if producer.email: to_email.append(producer.email) if producer.email2: to_email.append(producer.email2) if producer.email3: to_email.append(producer.email3) to_email = list(set(to_email + order_responsible.get_to_email)) email = RepanierEmail( subject=order_producer_mail_subject, html_body=html_body, to=to_email, ) if wb is not None: if producer.represent_this_buyinggroup: if abstract_ws is not None: wb.add_sheet(abstract_ws, index=0) email.attach( filename, save_virtual_workbook(wb), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) email.send_email() if everything: # Orders send to our customers only if they don't have already received it customer_set = Customer.objects.filter( represent_this_buyinggroup=False, customerinvoice__is_order_confirm_send=False, customerinvoice__permanence_id=permanence.id, language=language_code ).order_by('?') if len(deliveries_id) > 0: customer_set = customer_set.filter( customerinvoice__delivery_id__in=deliveries_id, ) for customer in customer_set: export_order_2_1_customer( customer, filename, permanence, order_responsible, abstract_ws ) customer_invoice = CustomerInvoice.objects.filter( customer_id=customer.id, permanence_id=permanence_id ).order_by('?').first() customer_invoice.confirm_order() customer_invoice.save() translation.activate(cur_language)
def send_invoice(permanence_id): from repanier.apps import REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER, \ REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER, \ REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG invoice_responsible = Staff.get_or_create_invoice_responsible() if REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER: # To the producer we speak of "payment". # This is the detail of the payment to the producer, i.e. received products for producer in Producer.objects.filter( permanence_id=permanence.id, language=language_code).order_by('?'): to_email = [] if producer.email: to_email.append(producer.email) if producer.email2: to_email.append(producer.email2) if producer.email3: to_email.append(producer.email3) if to_email: to_email = list( set(to_email + invoice_responsible["to_email"])) long_profile_name = producer.long_profile_name \ if producer.long_profile_name is not None else producer.short_profile_name if Purchase.objects.filter( permanence_id=permanence.id, producer_id=producer.id).order_by('?').exists(): invoice_producer_mail = config.safe_translation_getter( 'invoice_producer_mail', any_language=True, default=EMPTY_STRING) invoice_producer_mail_subject = "{} - {}".format( settings.REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(invoice_producer_mail) context = TemplateContext({ 'name': long_profile_name, 'long_profile_name': long_profile_name, 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('producer_invoice_uuid_view', args=(0, producer.uuid)), permanence)), 'signature': invoice_responsible["html_signature"] }) html_body = template.render(context) email = RepanierEmail( subject=invoice_producer_mail_subject, html_body=html_body, to=to_email) email.send_email() if REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER: # To the customer we speak of "invoice". # This is the detail of the invoice, i.e. sold products invoice_description = permanence.safe_translation_getter( 'invoice_description', any_language=True, default=EMPTY_STRING) for customer in Customer.objects.filter( customerinvoice__permanence_id=permanence.id, customerinvoice__customer_charged_id=F('customer_id'), represent_this_buyinggroup=False, language=language_code).order_by('?'): long_basket_name = customer.long_basket_name if customer.long_basket_name is not None else customer.short_basket_name if Purchase.objects.filter( permanence_id=permanence.id, customer_invoice__customer_charged_id=customer.id ).order_by('?').exists(): to_email = [customer.user.email] if customer.email2: to_email.append(customer.email2) to_email = list( set(to_email + invoice_responsible["to_email"])) invoice_customer_mail = config.safe_translation_getter( 'invoice_customer_mail', any_language=True, default=EMPTY_STRING) invoice_customer_mail_subject = "{} - {}".format( settings.REPANIER_SETTINGS_GROUP_NAME, permanence) customer_last_balance, _, customer_payment_needed, customer_order_amount = payment_message( customer, permanence) template = Template(invoice_customer_mail) context = TemplateContext({ 'name': long_basket_name, 'long_basket_name': long_basket_name, 'basket_name': customer.short_basket_name, 'short_basket_name': customer.short_basket_name, 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id, )), permanence)), 'last_balance_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('customer_invoice_view', args=(0, )), customer_last_balance)), 'last_balance': mark_safe(customer_last_balance), 'order_amount': mark_safe(customer_order_amount), 'payment_needed': mark_safe(customer_payment_needed), 'invoice_description': mark_safe(invoice_description), 'signature': invoice_responsible["html_signature"] }) html_body = template.render(context) email = RepanierEmail( subject=invoice_customer_mail_subject, html_body=html_body, to=to_email, show_customer_may_unsubscribe=True) email.send_email() translation.activate(cur_language)
def init_repanier(cls): from repanier.const import DECIMAL_ONE, PERMANENCE_NAME_PERMANENCE, CURRENCY_EUR from repanier.models.producer import Producer from repanier.models.bankaccount import BankAccount from repanier.models.staff import Staff from repanier.models.customer import Customer # Create the configuration record managed via the admin UI config = Configuration.objects.filter(id=DECIMAL_ONE).first() if config is not None: return config site = Site.objects.get_current() if site is not None: site.name = settings.REPANIER_SETTINGS_GROUP_NAME site.domain = settings.ALLOWED_HOSTS[0] site.save() config = Configuration.objects.create( group_name=settings.REPANIER_SETTINGS_GROUP_NAME, name=PERMANENCE_NAME_PERMANENCE, bank_account="BE99 9999 9999 9999", currency=CURRENCY_EUR ) config.init_email() config.save() # Create firsts users Producer.get_or_create_group() customer_buyinggroup = Customer.get_or_create_group() very_first_customer = Customer.get_or_create_the_very_first_customer() BankAccount.open_account( customer_buyinggroup=customer_buyinggroup, very_first_customer=very_first_customer ) coordinator = Staff.get_or_create_any_coordinator() Staff.get_or_create_order_responsible() Staff.get_or_create_invoice_responsible() # Create and publish first web page if not coordinator.is_webmaster: # This should not be the case... return from cms.models import StaticPlaceholder from cms.constants import X_FRAME_OPTIONS_DENY from cms import api page = api.create_page( title=_("Home"), soft_root=False, template=settings.CMS_TEMPLATE_HOME, language=settings.LANGUAGE_CODE, published=True, parent=None, xframe_options=X_FRAME_OPTIONS_DENY, in_navigation=True ) try: # New in CMS 3.5 page.set_as_homepage() except: pass placeholder = page.placeholders.get(slot="home-hero") api.add_plugin( placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_HERO) placeholder = page.placeholders.get(slot="home-col-1") api.add_plugin( placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_COL_1) placeholder = page.placeholders.get(slot="home-col-2") api.add_plugin( placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_COL_2) placeholder = page.placeholders.get(slot="home-col-3") api.add_plugin( placeholder=placeholder, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body=settings.CMS_TEMPLATE_HOME_COL_3) static_placeholder = StaticPlaceholder( code="footer", # site_id=1 ) static_placeholder.save() api.add_plugin( placeholder=static_placeholder.draft, plugin_type='TextPlugin', language=settings.LANGUAGE_CODE, body='hello world footer' ) static_placeholder.publish( request=None, language=settings.LANGUAGE_CODE, force=True ) api.publish_page( page=page, user=coordinator.user, language=settings.LANGUAGE_CODE) return config
def email_order(permanence_id, everything=True, producers_id=(), deliveries_id=()): from repanier.apps import REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD, \ REPANIER_SETTINGS_GROUP_NAME, \ REPANIER_SETTINGS_CONFIG cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) permanence = Permanence.objects.get(id=permanence_id) config = REPANIER_SETTINGS_CONFIG filename = "{}-{}.xlsx".format(_("Order"), permanence) order_responsible = Staff.get_or_create_order_responsible() if len(deliveries_id) > 0: # if closed deliveries_id is not empty list and not "None" then all_producers should be True everything = True for delivery_id in deliveries_id: # Send a recap of the orders to the responsible export_order_2_1_group(config, delivery_id, filename, permanence, order_responsible) if not everything: abstract_ws = None else: # Orders send to the preparation team, to the order_responsible wb, abstract_ws = generate_customer_xlsx( permanence=permanence, deliveries_id=deliveries_id) if wb is not None: # At least one order order_staff_mail = config.safe_translation_getter( 'order_staff_mail', any_language=True, default=EMPTY_STRING) order_staff_mail_subject = "{} - {}".format( REPANIER_SETTINGS_GROUP_NAME, permanence) board_composition, board_composition_and_description = get_board_composition( permanence.id) template = Template(order_staff_mail) context = TemplateContext({ 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id, )), permanence)), 'board_composition': mark_safe(board_composition), 'board_composition_and_description': mark_safe(board_composition_and_description), 'signature': order_responsible.get_html_signature }) html_body = template.render(context) if REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD: to_email = [] for permanence_board in PermanenceBoard.objects.filter( permanence_id=permanence.id).order_by('?'): if permanence_board.customer: to_email.append( permanence_board.customer.user.email) to_email = list( set(to_email + order_responsible.get_to_email)) else: to_email = list(set(order_responsible.get_to_email)) email = RepanierEmail( subject=order_staff_mail_subject, html_body=html_body, from_email=order_responsible.get_from_email, to=to_email, reply_to=order_responsible.get_reply_to_email) email.attach( filename, save_virtual_workbook(wb), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) email.send_email() # Orders send to our producers producer_set = Producer.objects.filter( permanence=permanence, language=language_code, ).order_by('?') if len(producers_id) > 0: producer_set = producer_set.filter(id__in=producers_id) for producer in producer_set: long_profile_name = producer.long_profile_name if producer.long_profile_name is not None else producer.short_profile_name wb = generate_producer_xlsx(permanence=permanence, producer=producer, wb=None) order_producer_mail = config.safe_translation_getter( 'order_producer_mail', any_language=True, default=EMPTY_STRING) order_producer_mail_subject = "{} - {}".format( REPANIER_SETTINGS_GROUP_NAME, permanence) template = Template(order_producer_mail) context = TemplateContext({ 'name': long_profile_name, 'long_profile_name': long_profile_name, 'order_empty': wb is None, 'duplicate': not (wb is None or producer.manage_replenishment), 'permanence_link': mark_safe("<a href=\"https://{}{}\">{}</a>".format( settings.ALLOWED_HOSTS[0], reverse('order_view', args=(permanence.id, )), permanence)), 'signature': order_responsible.get_html_signature }) html_body = template.render(context) producer_invoice = ProducerInvoice.objects.filter( producer_id=producer.id, permanence_id=permanence.id).order_by('?').first() to_email = [] if producer_invoice is not None \ and producer_invoice.get_total_price_with_tax() < producer.minimum_order_value: html_body = "{}<br><br>{}".format(order_producer_mail_subject, html_body) order_producer_mail_subject = _( '⚠ Mail not send to our producer {} because the minimum order value has not been reached.' ).format(long_profile_name) else: if producer.email: to_email.append(producer.email) if producer.email2: to_email.append(producer.email2) if producer.email3: to_email.append(producer.email3) to_email = list(set(to_email + order_responsible.get_to_email)) email = RepanierEmail( subject=order_producer_mail_subject, html_body=html_body, from_email=order_responsible.get_from_email, to=to_email, reply_to=order_responsible.get_reply_to_email) if wb is not None: if producer.represent_this_buyinggroup: if abstract_ws is not None: wb.add_sheet(abstract_ws, index=0) email.attach( filename, save_virtual_workbook(wb), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) email.send_email() if everything: # Orders send to our customers only if they don't have already received it # ==> customerinvoice__is_order_confirm_send=False # customerinvoice__permanence_id=permanence.id if not settings.REPANIER_SETTINGS_CUSTOMER_MUST_CONFIRM_ORDER: # -> Do not send cancelled orders customer_set = Customer.objects.filter( represent_this_buyinggroup=False, customerinvoice__is_order_confirm_send=False, customerinvoice__permanence_id=permanence.id, language=language_code).order_by('?') if len(deliveries_id) > 0: customer_set = customer_set.filter( customerinvoice__delivery_id__in=deliveries_id, ) for customer in customer_set: export_order_2_1_customer(customer, filename, permanence, order_responsible, abstract_ws) # confirm_customer_invoice(permanence_id, customer.id) customer_invoice = CustomerInvoice.objects.filter( customer_id=customer.id, permanence_id=permanence_id).order_by('?').first() customer_invoice.confirm_order() customer_invoice.save() translation.activate(cur_language)
def close_and_send_order(self, request, queryset): if "cancel" in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = queryset.first() if permanence.status not in [PERMANENCE_OPENED, PERMANENCE_CLOSED]: user_message = _( "The status of %(permanence)s prohibit you to perform this action." ) % { "permanence": permanence } user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return if "apply" in request.POST: all_deliveries = True if request.POST.get("all-deliveries", True) else False deliveries_to_be_send = request.POST.getlist("deliveries", []) logger.debug("all_deliveries : {}".format( request.POST.get("all-deliveries"))) logger.debug("all_deliveries : {}".format(all_deliveries)) logger.debug("deliveries_to_be_send : {}".format( request.POST.getlist("deliveries", []))) if (permanence.with_delivery_point and not all_deliveries and len(deliveries_to_be_send) == 0): user_message = _( "You must select at least one delivery point.") user_message_level = messages.WARNING self.message_user(request, user_message, user_message_level) return # close_and_send_order(permanence.id, all_deliveries, deliveries_to_be_send) t = threading.Thread( target=close_and_send_order, args=(permanence.id, all_deliveries, deliveries_to_be_send), ) t.start() user_message = _("The orders are being send.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return template_order_customer_mail = [] template_order_producer_mail = [] template_order_staff_mail = [] cur_language = translation.get_language() for language in settings.PARLER_LANGUAGES[settings.SITE_ID]: language_code = language["code"] translation.activate(language_code) template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG.order_customer_mail) staff = Staff.get_or_create_order_responsible() customer_last_balance = _( "The balance of your account as of %(date)s is %(balance)s." ) % { "date": timezone.now().strftime(settings.DJANGO_SETTINGS_DATE), "balance": RepanierMoney(123.45), } customer_on_hold_movement = _( "This balance does not take account of any unrecognized payments %(bank)s and any unbilled order %(other_order)s." ) % { "bank": RepanierMoney(123.45), "other_order": RepanierMoney(123.45) } bank_account_number = repanier.apps.REPANIER_SETTINGS_BANK_ACCOUNT if bank_account_number is not None: group_name = settings.REPANIER_SETTINGS_GROUP_NAME if permanence.short_name: communication = "{} ({})".format(_("Short name"), permanence.short_name) else: communication = _("Short name") customer_payment_needed = '<font color="#bd0926">{}</font>'.format( _("Please pay a provision of %(payment)s to the bank account %(name)s %(number)s with communication %(communication)s." ) % { "payment": RepanierMoney(123.45), "name": group_name, "number": bank_account_number, "communication": communication, }) else: customer_payment_needed = EMPTY_STRING context = TemplateContext({ "name": _("Long name"), "long_basket_name": _("Long name"), "basket_name": _("Short name"), "short_basket_name": _("Short name"), "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "last_balance": mark_safe('<a href="#">{}</a>'.format(customer_last_balance)), "order_amount": RepanierMoney(123.45), "on_hold_movement": mark_safe(customer_on_hold_movement), "payment_needed": mark_safe(customer_payment_needed), "delivery_point": _("Delivery point").upper(), "signature": staff.get_html_signature, }) template_order_customer_mail.append(language_code) template_order_customer_mail.append(template.render(context)) template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG.order_producer_mail) context = TemplateContext({ "name": _("Long name"), "long_profile_name": _("Long name"), "order_empty": False, "duplicate": True, "permanence_link": format_html('<a href="#">{}</a>', permanence), "signature": staff.get_html_signature, }) template_order_producer_mail.append(language_code) template_order_producer_mail.append(template.render(context)) board_composition = permanence.get_html_board_composition() template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG.order_staff_mail) context = TemplateContext({ "permanence_link": format_html('<a href="#">{}</a>', permanence), "board_composition": board_composition, "board_composition_and_description": board_composition, "signature": staff.get_html_signature, }) template_order_staff_mail.append(language_code) template_order_staff_mail.append(template.render(context)) translation.activate(cur_language) order_customer_email_will_be_sent, order_customer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=True) order_producer_email_will_be_sent, order_producer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=True) order_board_email_will_be_sent, order_board_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps. REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_BOARD, board=True, ) form = CloseAndSendOrderForm( initial={ "template_order_customer_mail": mark_safe("<br>==============<br>".join( template_order_customer_mail)), "template_order_producer_mail": mark_safe("<br>==============<br>".join( template_order_producer_mail)), "template_order_staff_mail": mark_safe("<br>==============<br>".join( template_order_staff_mail)), }) if permanence.with_delivery_point: deliveries = DeliveryBoard.objects.filter( permanence_id=permanence.id, status__in=[PERMANENCE_OPENED, PERMANENCE_CLOSED], ) else: deliveries = DeliveryBoard.objects.none() template_name = get_repanier_template_name( "confirm_admin_send_order.html") return render( request, template_name, { "sub_title": _("Please, confirm the action : send orders"), "action_checkbox_name": admin.ACTION_CHECKBOX_NAME, "action": "close_and_send_order", "permanence": permanence, "with_delivery_point": permanence.with_delivery_point, "deliveries": deliveries, "form": form, "order_customer_email_will_be_sent": order_customer_email_will_be_sent, "order_customer_email_will_be_sent_to": order_customer_email_will_be_sent_to, "order_producer_email_will_be_sent": order_producer_email_will_be_sent, "order_producer_email_will_be_sent_to": order_producer_email_will_be_sent_to, "order_board_email_will_be_sent": order_board_email_will_be_sent, "order_board_email_will_be_sent_to": order_board_email_will_be_sent_to, }, )
def send_invoices(self, request, permanence_qs): if "cancel" in request.POST: user_message = _("Action canceled by the user.") user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return permanence = permanence_qs.first() if permanence.status != PERMANENCE_INVOICED: user_message = _( "The status of %(permanence)s prohibit you to perform this action." ) % { "permanence": permanence } user_message_level = messages.ERROR self.message_user(request, user_message, user_message_level) return template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG.invoice_customer_mail) invoice_description = permanence.safe_translation_getter( "invoice_description", any_language=True, default=EMPTY_STRING) staff = Staff.get_or_create_invoice_responsible() # TODO : Align on tools.payment_message customer_order_amount = _( "The amount of your order is %(amount)s.") % { "amount": RepanierMoney(123.45) } customer_last_balance = _( "The balance of your account as of %(date)s is %(balance)s.") % { "date": timezone.now().strftime(settings.DJANGO_SETTINGS_DATE), "balance": RepanierMoney(123.45), } bank_account_number = repanier.apps.REPANIER_SETTINGS_BANK_ACCOUNT if bank_account_number is not None: group_name = settings.REPANIER_SETTINGS_GROUP_NAME if permanence.short_name: communication = "{} ({})".format(_("Short name"), permanence.short_name) else: communication = _("Short name") customer_payment_needed = '<font color="#bd0926">{}</font>'.format( _("Please pay a provision of %(payment)s to the bank account %(name)s %(number)s with communication %(communication)s." ) % { "payment": RepanierMoney(123.45), "name": group_name, "number": bank_account_number, "communication": communication, }) else: customer_payment_needed = EMPTY_STRING context = TemplateContext({ "name": _("Long name"), "long_basket_name": _("Long name"), "basket_name": _("Short name"), "short_basket_name": _("Short name"), "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "last_balance_link": mark_safe('<a href="#">{}</a>'.format(customer_last_balance)), "last_balance": customer_last_balance, "order_amount": mark_safe(customer_order_amount), "payment_needed": mark_safe(customer_payment_needed), "invoice_description": mark_safe(invoice_description), "signature": staff.get_html_signature, }) template_invoice_customer_mail = template.render(context) invoice_customer_email_will_be_sent, invoice_customer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps. REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_CUSTOMER) template = Template( repanier.apps.REPANIER_SETTINGS_CONFIG.invoice_producer_mail) context = TemplateContext({ "name": _("Long name"), "long_profile_name": _("Long name"), "permanence_link": mark_safe('<a href="#">{}</a>'.format(permanence)), "signature": staff.get_html_signature, }) template_invoice_producer_mail = template.render(context) invoice_producer_email_will_be_sent, invoice_producer_email_will_be_sent_to = RepanierEmail.send_email_to_who( is_email_send=repanier.apps. REPANIER_SETTINGS_SEND_INVOICE_MAIL_TO_PRODUCER) if "apply" in request.POST: form = InvoiceOrderForm(request.POST) if form.is_valid(): t = threading.Thread(target=email_invoice.send_invoice, args=(permanence.id, )) t.start() user_message = _( "Emails containing the invoices will be send to the customers and the producers." ) user_message_level = messages.INFO self.message_user(request, user_message, user_message_level) return HttpResponseRedirect(request.get_full_path()) else: form = InvoiceOrderForm( initial={ "template_invoice_customer_mail": mark_safe(template_invoice_customer_mail), "template_invoice_producer_mail": mark_safe(template_invoice_producer_mail), }) template_name = get_repanier_template_name( "confirm_admin_send_invoice.html") return render( request, template_name, { "sub_title": _("Please, confirm the action : send invoices"), "action_checkbox_name": admin.ACTION_CHECKBOX_NAME, "action": "send_invoices", "permanence": permanence, "form": form, "invoice_customer_email_will_be_sent": invoice_customer_email_will_be_sent, "invoice_customer_email_will_be_sent_to": invoice_customer_email_will_be_sent_to, "invoice_producer_email_will_be_sent": invoice_producer_email_will_be_sent, "invoice_producer_email_will_be_sent_to": invoice_producer_email_will_be_sent_to, }, )