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, )
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)
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, )
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, }, )
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, )
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, )
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)
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, )
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)
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), }, )
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))
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)