예제 #1
0
def _get_filters(filters):
    pe_clauses = [
        "pe.docstatus = 1",
        "pe.posting_date BETWEEN %(from_date)s AND %(to_date)s",
        "pe.mode_of_payment = 'Cheque'",
    ]
    je_clauses = [
        "je.docstatus = 1",
        "je.posting_date BETWEEN %(from_date)s AND %(to_date)s",
        "je.pb_is_cheque = 1",
    ]
    values = merge(
        pick(["customer", "branch"], filters),
        {
            "from_date": filters.date_range[0],
            "to_date": filters.date_range[1]
        },
    )
    return (
        {
            "pe_clauses": " AND ".join(pe_clauses),
            "je_clauses": " AND ".join(je_clauses),
        },
        values,
    )
예제 #2
0
    def set_items_from_reference(self):
        ref_doc = frappe.get_doc(self.print_dt, self.print_dn)

        if self.print_dt == "Stock Entry":
            self.set_warehouse = (ref_doc.from_warehouse if self.use_warehouse
                                  == "Source" else ref_doc.to_warehouse)
        else:
            self.set_warehouse = ref_doc.set_warehouse
            self.use_warehouse = None  # Target, Source

        self.items = []
        for ref_item in ref_doc.items:
            items = merge(
                pick(
                    [
                        "item_code", "item_name", "qty", "uom", "rate",
                        "warehouse"
                    ],
                    ref_item.as_dict(),
                ),
                {
                    "batch": ref_item.batch_no,
                    "expiry_date": _get_expiry_date(ref_item),
                    "actual_qty": _get_actual_qty(ref_item,
                                                  self.set_warehouse),
                },
            )
            self.append("items", items)
예제 #3
0
def _get_filters(doctype, filters):
    is_include = filters.vat_type not in ["Standard Rated", "Zero Rated"]
    vat_exempt_accounts = [
        x[0] for x in frappe.get_all(
            "POS Bahrain Settings Tax Category",
            filters={"category": filters.vat_type} if is_include else {},
            fields=["account"],
            as_list=1,
        )
    ]
    if not vat_exempt_accounts:
        msg = "Please setup {}: <em>VAT Tax Categories</em>".format(
            frappe.get_desk_link("POS Bahrain Settings", ""))
        if filters.get("hide_error_message"):
            raise VatCategoryNotFound(msg)
        else:
            frappe.throw(msg, exc=VatCategoryNotFound)

    inv_clauses = [
        "d.docstatus = 1",
        "d.posting_date BETWEEN %(from_date)s AND %(to_date)s",
        "IFNULL(dt.account_head, '') != ''",
        "dt.account_head {} %(tax_accounts)s".format(
            "IN" if is_include else "NOT IN"),
    ]
    glp_clauses = concatv(
        inv_clauses,
        ["d.payment_type IN %(payment_types)s", "a.account_type = 'Tax'"])
    values = merge(
        pick(["vat_type"], filters),
        {
            "from_date":
            filters.date_range[0],
            "to_date":
            filters.date_range[1],
            "tax_accounts":
            vat_exempt_accounts,
            "payment_types": ["Incoming"] if doctype == "Sales Invoice" else
            ["Outgoing", "Internal Transfer"],
        },
    )
    return (
        {
            "doctype":
            doctype,
            "item_doctype":
            "{} Item".format(doctype),
            "tax_doctype":
            "{} Taxes and Charges".format("Sales" if doctype ==
                                          "Sales Invoice" else "Purchase"),
            "party_name":
            "{}_name".format("customer" if doctype ==
                             "Sales Invoice" else "supplier"),
            "invoice_clauses":
            " AND ".join(inv_clauses),
            "glp_clauses":
            " AND ".join(glp_clauses),
        },
        values,
    )
예제 #4
0
 def make_invoice(invoice):
     return merge(
         pick(["grand_total", "paid_amount", "change_amount"], invoice),
         {
             "invoice": invoice.name,
             "total_qty": invoice.pos_total_qty
         },
     )
 def make_invoice(invoice):
     return merge(
         pick(["grand_total", "paid_amount", "change_amount"], invoice),
         {
             "invoice": invoice.name,
             "total_quantity": invoice.pos_total_qty,
             "sales_employee": invoice.pb_sales_employee,
         },
     )
예제 #6
0
def _get_filters(filters):
    clauses = concatv(
        ["sle.posting_date BETWEEN %(from_date)s AND %(to_date)s"],
        ["sle.item_code = %(item_code)s"],
    )
    values = merge(
        pick(["item_code", "price_list"], filters),
        {"from_date": filters.date_range[0], "to_date": filters.date_range[1]},
    )
    return (
        {"clauses": " AND ".join(clauses)},
        values,
    )
예제 #7
0
def _get_filters(doctype, filters):
    vat_exempt_accounts = [
        x[0] for x in frappe.get_all(
            "POS Bahrain Settings Tax Exempt", fields=["account"], as_list=1)
    ]
    if not vat_exempt_accounts:
        frappe.throw(
            frappe._("Please set {}: <em>VAT Exempt Accounts</em>".format(
                frappe.get_desk_link("POS Bahrain Settings", ""))))
    inv_clauses = [
        "d.docstatus = 1",
        "d.posting_date BETWEEN %(from_date)s AND %(to_date)s",
        "IFNULL(dt.account_head, '') != ''",
        "dt.account_head {} %(tax_accounts)s".format(
            "IN" if filters.vat_type == "exempt" else "NOT IN"),
    ]
    glp_clauses = concatv(
        inv_clauses,
        ["d.payment_type IN %(payment_types)s", "a.account_type = 'Tax'"])
    values = merge(
        pick(["vat_type"], filters),
        {
            "from_date":
            filters.date_range[0],
            "to_date":
            filters.date_range[1],
            "tax_accounts":
            vat_exempt_accounts,
            "payment_types": ["Incoming"] if doctype == "Sales Invoice" else
            ["Outgoing", "Internal Transfer"],
        },
    )
    return (
        {
            "doctype":
            doctype,
            "item_doctype":
            "{} Item".format(doctype),
            "tax_doctype":
            "{} Taxes and Charges".format("Sales" if doctype ==
                                          "Sales Invoice" else "Purchase"),
            "party_name":
            "{}_name".format("customer" if doctype ==
                             "Sales Invoice" else "supplier"),
            "invoice_clauses":
            " AND ".join(inv_clauses),
            "glp_clauses":
            " AND ".join(glp_clauses),
        },
        values,
    )
예제 #8
0
 def on_update_after_submit(self):
     if self.workflow_state == "Received":
         self.validate_reference(RECEIVE)
         warehouses = self.get_warehouses(incoming=True)
         accounts = self.get_accounts()
         ref_doc = _make_stock_entry(
             merge(
                 pick(["company"], self.as_dict()),
                 warehouses,
                 {
                     "items": _map_items(warehouses, accounts)(self.items),
                     "pb_reference_stock_transfer": self.name,
                 },
                 _destruct_datetime(self.incoming_datetime),
             ))
         self.set_ref_doc("incoming_stock_entry", ref_doc)
예제 #9
0
 def on_submit(self):
     if self.workflow_state == "In Transit":
         self.validate_reference(DISPATCH)
         warehouses = self.get_warehouses(incoming=False)
         accounts = self.get_accounts()
         ref_doc = _make_stock_entry(
             merge(
                 pick(["company"], self.as_dict()),
                 warehouses,
                 {
                     "items": _map_items(warehouses, accounts)(self.items),
                     "pb_reference_stock_transfer": self.name,
                 },
                 _destruct_datetime(self.outgoing_datetime),
             ))
         self.set_ref_doc("outgoing_stock_entry", ref_doc)
def _get_filters(filters, transaction_type):
    clauses = concatv(
        [
            "inv.docstatus = 1",
            "inv.posting_date BETWEEN %(from_date)s AND %(to_date)s",
            "inv.company = %(company)s",
        ],
        ["inv_item.item_code = %(item_code)s"] if filters.item_code else [],
        ["INSTR(inv_item.item_name, %(item_name)s) > 0"]
        if filters.item_name else [],
        ["inv_item.item_group = %(item_group)s"] if filters.item_group else [],
        ["inv.customer = %(customer)s"] if filters.customer else [],
        ["inv.supplier = %(supplier)s"] if filters.supplier else [],
        ["inv_item.warehouse = %(warehouse)s"] if filters.warehouse else [],
    )
    bin_clauses = concatv(
        ["TRUE"], ["warehouse = %(warehouse)s"] if filters.warehouse else [])
    values = merge(
        pick(
            [
                "customer",
                "supplier",
                "company",
                "warehouse",
                "item_code",
                "item_name",
                "item_group",
            ],
            filters,
        ),
        {
            "from_date": filters.date_range[0],
            "to_date": filters.date_range[1]
        },
    )
    return (
        {
            "clauses": " AND ".join(clauses),
            "bin_clauses": " AND ".join(bin_clauses),
            "transaction_type": transaction_type,
        },
        values,
    )
예제 #11
0
 def set_items_from_reference(self):
     ref_doc = frappe.get_doc(self.print_dt, self.print_dn)
     self.set_warehouse = ref_doc.set_warehouse
     self.items = []
     for ref_item in ref_doc.items:
         items = merge(
             pick(
                 [
                     "item_code", "item_name", "qty", "uom", "rate",
                     "warehouse"
                 ],
                 ref_item.as_dict(),
             ),
             {
                 "batch": ref_item.batch_no,
                 "expiry_date": _get_expiry_date(ref_item),
                 "actual_qty": _get_actual_qty(ref_item),
             },
         )
         self.append("items", items)
예제 #12
0
 def make_payment(payment):
     mop_conversion_rate = (
         payment.amount / payment.mop_amount if payment.mop_amount else 1
     )
     expected_amount = (
         payment.amount - sum_by("change_amount", sales)
         if payment.is_default
         else (payment.mop_amount or payment.amount)
     )
     return merge(
         pick(["is_default", "mode_of_payment", "type"], payment),
         {
             "mop_conversion_rate": mop_conversion_rate,
             "collected_amount": expected_amount,
             "expected_amount": expected_amount,
             "difference_amount": 0,
             "mop_currency": payment.mop_currency
             or frappe.defaults.get_global_default("currency"),
             "base_collected_amount": expected_amount * flt(mop_conversion_rate),
         },
     )
예제 #13
0
    def set_report_details(self):
        args = merge(
            pick(["user", "pos_profile", "company"], self.as_dict()),
            {
                "period_from": self.period_from or now(),
                "period_to": self.period_to or now(),
            },
        )

        sales, returns = _get_invoices(args)
        actual_payments = _get_payments(args)
        taxes = _get_taxes(args)

        def make_invoice(invoice):
            return merge(
                pick(["grand_total", "paid_amount", "change_amount"], invoice),
                {
                    "invoice": invoice.name,
                    "total_qty": invoice.pos_total_qty
                },
            )

        def make_payment(payment):
            mop_conversion_rate = (payment.amount / payment.mop_amount
                                   if payment.mop_amount else 1)
            expected_amount = (payment.amount - sum_by("change_amount", sales)
                               if payment.is_default else
                               (payment.mop_amount or payment.amount))
            return merge(
                pick(["is_default", "mode_of_payment", "type"], payment),
                {
                    "mop_conversion_rate":
                    mop_conversion_rate,
                    "collected_amount":
                    expected_amount,
                    "expected_amount":
                    expected_amount,
                    "difference_amount":
                    0,
                    "mop_currency":
                    payment.mop_currency
                    or frappe.defaults.get_global_default("currency"),
                    "base_collected_amount":
                    expected_amount * flt(mop_conversion_rate),
                },
            )

        make_tax = partial(pick, ["rate", "tax_amount"])

        self.returns_total = sum_by("grand_total", returns)
        self.returns_net_total = sum_by("net_total", returns)
        self.grand_total = sum_by("grand_total", sales + returns)
        self.net_total = sum_by("net_total", sales + returns)
        self.outstanding_total = sum_by("outstanding_amount", sales)
        self.total_invoices = len(sales + returns)
        self.average_sales = sum_by("net_total",
                                    sales) / len(sales) if sales else 0
        self.total_quantity = sum_by("pos_total_qty", sales)
        self.returns_quantity = -sum_by("pos_total_qty", returns)
        self.tax_total = sum_by("tax_amount", taxes)
        self.discount_total = sum_by("discount_amount", sales)
        self.change_total = sum_by("change_amount", sales)

        self.invoices = []
        for invoice in sales:
            self.append("invoices", make_invoice(invoice))
        self.returns = []
        for invoice in returns:
            self.append("returns", make_invoice(invoice))

        existing_payments = self.payments

        def get_form_collected(mop):
            existing = compose(
                excepts(StopIteration, first, lambda x: None),
                partial(filter, lambda x: x.mode_of_payment == mop),
            )(existing_payments)
            if not existing or existing.collected_amount == existing.expected_amount:
                return {}
            return {"collected_amount": existing.collected_amount}

        self.payments = []
        for payment in actual_payments:
            self.append(
                "payments",
                merge(make_payment(payment),
                      get_form_collected(payment.mode_of_payment)),
            )
        self.taxes = []
        for tax in taxes:
            self.append("taxes", make_tax(tax))
예제 #14
0
    def set_report_details(self):
        args = merge(
            pick(["user", "pos_profile", "company"], self.as_dict()),
            {
                "period_from": get_datetime(self.period_from),
                "period_to": get_datetime(self.period_to),
            },
        )

        sales, returns = _get_invoices(args)
        actual_payments, collection_payments = _get_payments(args)
        taxes = _get_taxes(args)

        def make_invoice(invoice):
            return merge(
                pick(["grand_total", "paid_amount", "change_amount"], invoice),
                {
                    "invoice": invoice.name,
                    "total_quantity": invoice.pos_total_qty,
                    "sales_employee": invoice.pb_sales_employee,
                },
            )

        def make_payment(payment):
            mop_conversion_rate = (payment.amount / payment.mop_amount
                                   if payment.mop_amount else 1)
            expected_amount = (payment.amount - sum_by("change_amount", sales)
                               if payment.is_default else
                               (payment.mop_amount or payment.amount))
            return merge(
                pick(["is_default", "mode_of_payment", "type"], payment),
                {
                    "mop_conversion_rate":
                    mop_conversion_rate,
                    "collected_amount":
                    expected_amount,
                    "expected_amount":
                    expected_amount,
                    "difference_amount":
                    0,
                    "mop_currency":
                    payment.mop_currency
                    or frappe.defaults.get_global_default("currency"),
                    "base_collected_amount":
                    expected_amount * flt(mop_conversion_rate),
                },
            )

        make_tax = partial(pick, ["rate", "tax_amount"])
        get_employees = partial(
            pick,
            ["pb_sales_employee", "pb_sales_employee_name", "grand_total"])

        self.returns_total = sum_by("grand_total", returns)
        self.returns_net_total = sum_by("net_total", returns)
        self.grand_total = sum_by("grand_total", sales + returns)
        self.net_total = sum_by("net_total", sales + returns)
        self.outstanding_total = sum_by("outstanding_amount", sales)
        self.total_invoices = len(sales + returns)
        self.average_sales = sum_by("net_total",
                                    sales) / len(sales) if sales else 0
        self.total_quantity = sum_by("pos_total_qty", sales)
        self.returns_quantity = -sum_by("pos_total_qty", returns)
        self.tax_total = sum_by("tax_amount", taxes)
        self.discount_total = sum_by("discount_amount", sales)
        self.change_total = sum_by("change_amount", sales)
        self.total_collected = (sum_by("amount", actual_payments) +
                                sum_by("amount", collection_payments) -
                                self.change_total)

        self.invoices = []
        for invoice in sales:
            self.append("invoices", make_invoice(invoice))
        self.returns = []
        for invoice in returns:
            self.append("returns", make_invoice(invoice))

        existing_payments = self.payments

        def get_form_collected(mop):
            existing = compose(
                excepts(StopIteration, first, lambda x: None),
                partial(filter, lambda x: x.mode_of_payment == mop),
            )(existing_payments)
            if not existing or existing.collected_amount == existing.expected_amount:
                return {}
            return {"collected_amount": existing.collected_amount}

        self.payments = []
        for payment in actual_payments:
            self.append(
                "payments",
                merge(make_payment(payment),
                      get_form_collected(payment.mode_of_payment)),
            )
        for payment in collection_payments:
            collected_payment = merge(
                make_payment(payment),
                get_form_collected(payment.mode_of_payment))
            existing_payment = list(
                filter(
                    lambda x: x.mode_of_payment == collected_payment[
                        "mode_of_payment"],
                    self.payments,
                ))[0]
            if existing_payment:
                for field in [
                        "expected_amount",
                        "collected_amount",
                        "difference_amount",
                        "base_collected_amount",
                ]:
                    existing_payment.set(
                        field,
                        sum([
                            existing_payment.get(field),
                            collected_payment.get(field, 0),
                        ]),
                    )
            else:
                self.append("payments", collected_payment)

        self.taxes = []
        for tax in taxes:
            self.append("taxes", make_tax(tax))

        self.employees = []
        employee_with_sales = compose(list, partial(map, get_employees))(sales)
        employees = compose(
            list, unique,
            partial(map,
                    lambda x: x["pb_sales_employee"]))(employee_with_sales)
        for employee in employees:
            sales_employee_name = compose(
                first,
                partial(filter, lambda x: x["pb_sales_employee"] == employee))(
                    employee_with_sales)["pb_sales_employee_name"]
            sales = compose(
                list,
                partial(map, lambda x: x["grand_total"]),
                partial(filter, lambda x: x["pb_sales_employee"] == employee),
            )(employee_with_sales)
            self.append(
                "employees",
                {
                    "sales_employee": employee,
                    "sales_employee_name": sales_employee_name,
                    "invoices_count": len(sales),
                    "sales_total": sum(sales),
                },
            )

        self.item_groups = []
        for row in _get_item_groups(args):
            self.append("item_groups", row)