Ejemplo n.º 1
0
    def send_emails(self):
        if not self.email_template:
            frappe.throw(frappe._("Email Template required to send emails"))

        subject, response = frappe.get_cached_value(
            "Email Template", self.email_template, ["subject", "response"]
        )
        get_first_details = excepts(StopIteration, first, lambda _: {})

        for contact_email, invoices in groupby(
            "contact_email", [x.as_dict() for x in self.invoices if x.contact_email]
        ).items():
            context = merge(
                get_first_details(invoices), {"batch": self.batch, "invoices": invoices}
            )

            _subject = frappe.render_template(subject, context)
            _message = frappe.render_template(response, context)
            frappe.sendmail(
                recipients=[contact_email],
                subject=_subject,
                message=_message,
                reference_doctype="Sales Invoice",
                reference_name=context.get("sales_invoice"),
            )
Ejemplo n.º 2
0
def _update_freight(bo, si):
    get_freight_row = compose(
        excepts(StopIteration, first, lambda _: None),
        lambda name: filter(lambda x: x.name == name, bo.freight),
    )
    for sii in [x for x in si.items if x.gg_update_freight]:
        freight = get_freight_row(sii.gg_bo_detail)
        if freight:
            freight.based_on = frappe.get_cached_value("Item", sii.item_code,
                                                       "gg_freight_based_on")
            if freight.based_on == "Packages":
                freight.no_of_packages = sii.qty
            elif freight.based_on == "Weight":
                freight.weight_actual = sii.qty
            freight.rate = sii.rate
            freight.amount = sii.amount
Ejemplo n.º 3
0
def _send_partner_assignment(doc):
    order = _get_so(doc)
    if not order:
        return
    fcm_token = frappe.get_cached_value("Sales Partner", doc.sales_partner,
                                        "le_fcm_token")
    if not fcm_token:
        return

    get_address = compose(
        json.dumps,
        list,
        filter(None),
        excepts(
            frappe.DoesNotExistError,
            lambda x: frappe.get_cached_value(
                "Address",
                x,
                ["address_line1", "address_line2"],
            ),
            lambda _: [],
        ),
    )

    data = {
        "type":
        "job_assigment",
        "note_id":
        doc.name,
        "items":
        json.dumps([x.item_name for x in doc.items]),
        "scheduled_datetime":
        frappe.utils.get_datetime_str(doc.le_scheduled_datetime),
        "customer_name":
        doc.customer_name,
        "address":
        get_address(doc.shipping_address_name or doc.customer_address),
    }

    send_data(fcm_token, data)
Ejemplo n.º 4
0
def _get_root_groups():
    def get_root(x):
        # assuming that parent - child relationship is never circular
        parent = get_parent(x)
        if parent:
            return get_root(parent)
        return x

    groups = frappe.get_all(
        "Item Group",
        fields=["name", "parent_item_group"],
        filters={"show_in_website": 1},
    )
    get_parent = compose(
        excepts(StopIteration, first, lambda _: None),
        lambda x: filter(lambda y: y.get("name") == x.get("parent_item_group"),
                         groups),
    )
    make_unique_roots = compose(list, unique, map(lambda x: x.get("name")),
                                map(get_root))

    return make_unique_roots(groups)
Ejemplo n.º 5
0
def _validate_freight_qty(doc):
    bo = frappe.get_cached_doc("Booking Order", doc.gg_booking_order)
    get_freight_row = compose(
        excepts(StopIteration, first, lambda _: None),
        lambda x: filter(lambda row: row.name == x, bo.freight),
    )

    for item in doc.items:
        if item.gg_bo_detail:
            freight_row = get_freight_row(item.gg_bo_detail)
            if not freight_row:
                frappe.throw(
                    frappe.
                    _("Invalid Booking Order Freight Detail found in row #{} for {}"
                      .format(item.idx,
                              frappe.get_desk_link("Sales Invoice",
                                                   doc.name))))

            total_qty = (frappe.get_all(
                "Sales Invoice Item",
                filters={
                    "docstatus": 1,
                    "gg_bo_detail": item.gg_bo_detail
                },
                fields=["sum(qty)"],
                as_list=1,
            )[0][0] or 0)
            if total_qty + item.qty > _get_freight_qty(freight_row):
                frappe.throw(
                    frappe.
                    _("Total Qty in #{} for {} will exceed Freight Qty declared in {}"
                      .format(
                          item.idx,
                          frappe.get_desk_link("Sales Invoice", doc.name),
                          frappe.get_desk_link("Booking Order",
                                               doc.gg_booking_order),
                      )))
Ejemplo n.º 6
0
    def deliver(self, bo_detail, qty, unit, posting_datetime=None):
        deliverable = get_deliverable(bo_detail, self.destination_station)
        if qty > deliverable.get("qty"):
            frappe.throw(
                frappe._("Cannot deliver more than {} units".format(qty)))

        get_row = compose(
            excepts(StopIteration, first, lambda _: {}),
            filter(lambda x: x.get("name") == bo_detail),
        )
        row = get_row(self.freight)
        if not row:
            frappe.throw(frappe._("Invalid item"))

        conversion_factor = get_loading_conversion_factor(
            qty, unit, row.get("no_of_packages"), row.get("weight_actual"))
        if not conversion_factor:
            frappe.throw(frappe._("Invalid conversion factor"))

        no_of_packages = row.get("no_of_packages") * conversion_factor
        weight_actual = row.get("weight_actual") * conversion_factor

        _posting_datetime = posting_datetime or frappe.utils.now()
        frappe.get_doc({
            "doctype": "Booking Log",
            "posting_datetime": _posting_datetime,
            "booking_order": self.name,
            "station": self.destination_station,
            "activity": "Collected",
            "loading_unit": unit,
            "no_of_packages": -no_of_packages,
            "weight_actual": -weight_actual,
            "bo_detail": bo_detail,
        }).insert(ignore_permissions=True)

        self.set_as_completed()
Ejemplo n.º 7
0
import frappe
import sys, traceback
from toolz.curried import compose, excepts


def handle_error(fn):
    def wrapper(*args, **kwargs):
        if "cmd" in kwargs.keys():
            del kwargs["cmd"]
        try:
            return fn(*args, **kwargs)
        except Exception as e:
            frappe.logger("leiteng").error(e)
            traceback.print_exc(file=sys.stdout)

    return wrapper


transform_route = compose(
    excepts(AttributeError, lambda x: x.replace("/", "__"), lambda _: None),
    lambda x: x.get("route"),
)
Ejemplo n.º 8
0
def get_items(page="1",
              field_filters=None,
              attribute_filters=None,
              search=None):
    other_fieldnames = ["item_group", "thumbnail", "has_variants"]
    price_list = frappe.db.get_single_value("Shopping Cart Settings",
                                            "price_list")
    products_per_page = frappe.db.get_single_value("Products Settings",
                                                   "products_per_page")
    get_item_groups = compose(
        list,
        unique,
        map(lambda x: x.get("name")),
        concat,
        map(lambda x: get_child_nodes("Item Group", x)
            if x and frappe.db.exists("Item Group", x, cache=True) else []),
    )
    get_other_fields = compose(
        valmap(excepts(StopIteration, first, lambda _: {})),
        groupby("name"),
        lambda item_codes: frappe.db.sql(
            """
                SELECT name, {other_fieldnames}
                FROM `tabItem`
                WHERE name IN %(item_codes)s
            """.format(other_fieldnames=", ".join(other_fieldnames)),
            values={"item_codes": item_codes},
            as_dict=1,
        ),
        lambda items: [x.get("name") for x in items],
    )

    get_page_count = compose(
        lambda x: frappe.utils.ceil(x[0][0] / products_per_page),
        lambda x: frappe.db.sql(
            """
                SELECT COUNT(name) FROM `tabItem` WHERE
                    show_in_website = 1 AND
                    item_group IN %(item_groups)s
            """,
            values={"item_groups": x},
        ),
    )

    field_dict = (frappe.parse_json(field_filters) if isinstance(
        field_filters, str) else field_filters) or {}
    item_groups = (get_item_groups(field_dict.get("item_group"))
                   if field_dict.get("item_group") else None)

    frappe.form_dict.start = (frappe.utils.cint(page) - 1) * products_per_page
    items = get_products_for_website(
        field_filters=merge(
            field_dict, {"item_group": item_groups} if item_groups else {}),
        attribute_filters=frappe.parse_json(attribute_filters),
        search=search,
    )
    other_fields = get_other_fields(items) if items else {}
    item_prices = _get_item_prices(price_list, items) if items else {}

    get_rates = _rate_getter(price_list, item_prices)

    return {
        "page_count":
        get_page_count(item_groups) if item_groups else 0,
        "items": [
            merge(
                x,
                {
                    "route":
                    transform_route(x),
                    "description":
                    frappe.utils.strip_html_tags(x.get("description") or ""),
                },
                get_rates(x.get("name")),
                {
                    k: other_fields.get(x.get("name"), {}).get(k)
                    for k in other_fieldnames
                },
            ) for x in items
        ],
    }
Ejemplo n.º 9
0
    images = get_values(item_code, )
    template_images = get_values(variant_of) if variant_of else {}

    def get_image(field):
        return images.get(field) or template_images.get(field)

    return {
        "thumbnail": get_image("thumbnail"),
        "image": get_image("image"),
        "website_image": get_image("website_image"),
        "slideshow": get_slideshows(get_image("slideshow")),
    }


_get_item_prices = compose(
    valmap(excepts(StopIteration, first, lambda _: {})),
    groupby("item_code"),
    lambda price_list, items: frappe.db.sql(
        """
            SELECT item_code, price_list_rate
            FROM `tabItem Price`
            WHERE price_list = %(price_list)s AND item_code IN %(item_codes)s
        """,
        values={
            "price_list": price_list,
            "item_codes": [x.get("name") for x in items]
        },
        as_dict=1,
    ) if price_list else {},
)
Ejemplo n.º 10
0
 def get_mop_amount(mode_of_payment=None, payments=[]):
     return compose(
         lambda x: x.get("amount"),
         excepts(StopIteration, first, lambda x: {"amount": 0}),
         filter(lambda x: x.get("mode_of_payment") == mode_of_payment),
     )(payments)