Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions posnext/overrides/pos_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from erpnext.accounts.doctype.pos_invoice.pos_invoice import (
get_bin_qty,
get_bundle_availability,
get_pos_reserved_qty,
)


Expand All @@ -10,14 +11,13 @@ def get_stock_availability(item_code: str, warehouse: str) -> tuple:
if frappe.db.get_value("Item", item_code, "is_stock_item"):
is_stock_item = True
bin_qty = get_bin_qty(item_code, warehouse)
# pos_sales_qty = get_pos_reserved_qty(item_code, warehouse)
pos_sales_qty = get_pos_reserved_qty(item_code, warehouse)

return bin_qty, is_stock_item
return bin_qty - pos_sales_qty, is_stock_item
else:
is_stock_item = True
if frappe.db.exists("Product Bundle", {"name": item_code, "disabled": 0}):
return get_bundle_availability(item_code, warehouse), is_stock_item
else:
is_stock_item = False
# Is a service item or non_stock item
return 0, is_stock_item
25 changes: 22 additions & 3 deletions posnext/posnext/page/posnext/point_of_sale.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,18 @@ def get_items(
"custom_show_alternative_item_for_pos_search",
"custom_show_logical_rack",
"custom_skip_stock_transaction_validation",
"selling_price_list",
],
as_dict=False,
)

if not result:
frappe.throw(f"POS Profile {pos_profile} not found")

# Ensure we have exactly 6 values
if not isinstance(result, (tuple, list)) or len(result) != 6:
# Ensure we have exactly 7 values
if not isinstance(result, (tuple, list)) or len(result) != 7:
frappe.throw(
f"Invalid POS Profile configuration. Expected 6 fields but got {len(result) if isinstance(result, (tuple, list)) else 'invalid response'}"
f"Invalid POS Profile configuration. Expected 7 fields but got {len(result) if isinstance(result, (tuple, list)) else 'invalid response'}"
)

(
Expand All @@ -152,6 +153,7 @@ def get_items(
custom_show_alternative_item_for_pos_search,
custom_show_logical_rack,
custom_skip_stock_transaction_validation,
pos_profile_price_list,
) = result

result = []
Expand Down Expand Up @@ -293,6 +295,23 @@ def get_items(
limit=1,
)

if (
not item_price
and price_list != pos_profile_price_list
and pos_profile_price_list
):
item_price = frappe.get_all(
"Item Price",
fields=["price_list_rate", "currency", "uom", "batch_no"],
filters={
"price_list": pos_profile_price_list,
"item_code": item.item_code,
"selling": True,
},
order_by="creation desc",
limit=1,
)

if not item_price:
result.append(item)

Expand Down
9 changes: 9 additions & 0 deletions posnext/public/js/pos_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,15 @@ posnext.PointOfSale.Controller = class {
this.customer_details = details;
// will add/remove LP payment method
this.payment.render_loyalty_points_payment_mode();
// refresh item prices using the customer's own price list, bypassing
// doc.selling_price_list which may not be updated yet at this point
if (details && details.default_price_list) {
this.item_selector.filter_items({
price_list: details.default_price_list,
});
} else {
this.item_selector.filter_items();
}
},
},
});
Expand Down
16 changes: 16 additions & 0 deletions posnext/public/js/pos_item_cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -806,6 +806,7 @@ posnext.PointOfSale.ItemCart = class {
"mobile_no",
"image",
"loyalty_program",
"default_price_list",
])
.then(({ message }) => {
const { loyalty_program } = message;
Expand Down Expand Up @@ -1031,6 +1032,20 @@ posnext.PointOfSale.ItemCart = class {
}
}

refresh_totals_display() {
const frm = this.events.get_frm();
if (!frm || !frm.doc) return;
const items = frm.doc.items || [];
this.render_net_total(items);
this.render_total_item_qty(items);
let grand_total = cint(frappe.sys_defaults.disable_rounded_total)
? frm.doc.grand_total
: frm.doc.rounded_total;
if (!items.length && Math.abs(grand_total) != 0.005) grand_total = 0.0;
this.render_grand_total(grand_total);
this.render_taxes(frm.doc.taxes);
}

update_totals_section(frm) {
if (!frm) frm = this.events.get_frm();
frm.cscript.calculate_taxes_and_totals();
Expand Down Expand Up @@ -1174,6 +1189,7 @@ posnext.PointOfSale.ItemCart = class {
this.highlight_checkout_btn(true);

this.update_empty_cart_section(no_of_cart_items);
this.refresh_totals_display();
}

render_cart_item(item_data, $item_to_update) {
Expand Down
11 changes: 7 additions & 4 deletions posnext/public/js/pos_item_details.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ posnext.PointOfSale.ItemDetails = class {
init_child_components() {
this.$component.html(
`<div class="item-details-header">
<div class="label">${__("Item Detailss")}</div>
<div class="label">${__("Item Details")}</div>
<div class="close-btn">
<svg width="32" height="32" viewBox="0 0 14 14" fill="none">
<path d="M4.93764 4.93759L7.00003 6.99998M9.06243 9.06238L7.00003 6.99998M7.00003 6.99998L4.93764 9.06238L9.06243 4.93759" stroke="#8D99A6"/>
Expand All @@ -40,17 +40,19 @@ posnext.PointOfSale.ItemDetails = class {
<div class="item-display">
<div class="item-name-desc-price">
<div class="item-name"></div>
<div class="item-desc"></div>
<div class="item-code"></div>
<div class="item-price"></div>
</div>
<div class="item-image"></div>
</div>
<div class="discount-section"></div>
<div class="form-container"></div>
<div class="serial-batch-container"></div>`,
<div class="serial-batch-container"></div>
<div class="item-desc"></div>`,
);

this.$item_name = this.$component.find(".item-name");
this.$item_code = this.$component.find(".item-code");
this.$item_description = this.$component.find(".item-desc");
this.$item_price = this.$component.find(".item-price");
this.$item_image = this.$component.find(".item-image");
Expand Down Expand Up @@ -121,7 +123,7 @@ posnext.PointOfSale.ItemDetails = class {
}

render_dom(item) {
let { item_name, description, image, price_list_rate } = item;
let { item_name, item_code, description, image, price_list_rate } = item;

function get_description_html() {
if (description) {
Expand All @@ -135,6 +137,7 @@ posnext.PointOfSale.ItemDetails = class {
}

this.$item_name.html(item_name);
this.$item_code.html(item_code);
this.$item_description.html(get_description_html());
this.$item_price.html(format_currency(price_list_rate, this.currency));
if (!this.hide_images && image) {
Expand Down
16 changes: 11 additions & 5 deletions posnext/public/js/pos_item_selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,9 +337,15 @@ posnext.PointOfSale.ItemSelector = class {
});
}

get_items({ start = 0, page_length = 40, search_term = "" }) {
get_items({
start = 0,
page_length = 40,
search_term = "",
price_list: price_list_override = null,
}) {
const doc = this.events.get_frm().doc;
const price_list = (doc && doc.selling_price_list) || this.price_list;
const price_list =
price_list_override || (doc && doc.selling_price_list) || this.price_list;
let { item_group, pos_profile } = this;

!item_group && (item_group = this.parent_item_group);
Expand Down Expand Up @@ -716,7 +722,7 @@ posnext.PointOfSale.ItemSelector = class {
df: {
label: __("Search"),
fieldtype: "Data",
placeholder: __("Search by serial number or barcode"),
placeholder: __("Search by item code, name, barcode, or serial number"),
},
parent: this.$component.find(".search-field"),
render_input: true,
Expand Down Expand Up @@ -952,7 +958,7 @@ posnext.PointOfSale.ItemSelector = class {
});
}

filter_items({ search_term = "" } = {}) {
filter_items({ search_term = "", price_list = null } = {}) {
if (search_term) {
search_term = search_term.toLowerCase();

Expand All @@ -969,7 +975,7 @@ posnext.PointOfSale.ItemSelector = class {
}
}

this.get_items({ search_term }).then(({ message }) => {
this.get_items({ search_term, price_list }).then(({ message }) => {
const { items, serial_no, batch_no, barcode } = message;
if (search_term && !barcode) {
this.search_index[search_term] = items;
Expand Down
3 changes: 3 additions & 0 deletions posnext/public/js/pos_payment.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ posnext.PointOfSale.Payment = class {
this.custom_edit_rate = settings.custom_edit_rate_and_uom;
this.custom_show_credit_sales = settings.custom_show_credit_sales;
this.default_payment = settings.default_payment;
this.disable_grand_total_to_default_mop =
settings.disable_grand_total_to_default_mop;
this.current_payments = [];
this.enable_coupon_code = settings.enable_coupon_code;

Expand Down Expand Up @@ -593,6 +595,7 @@ posnext.PointOfSale.Payment = class {
}

focus_on_default_mop() {
if (this.disable_grand_total_to_default_mop) return;
const doc = this.events.get_frm().doc;
const payments = doc.payments;
payments.forEach((p) => {
Expand Down
Loading