Compare commits
28 Commits
v11.0.3-be
...
v10.1.64
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38eaaade89 | ||
|
|
2a98e59bd4 | ||
|
|
03348364e9 | ||
|
|
83fd31973f | ||
|
|
ac64b39562 | ||
|
|
c73c576536 | ||
|
|
034429b34d | ||
|
|
874866e9f9 | ||
|
|
c365ce8f21 | ||
|
|
3a11f34355 | ||
|
|
91eac5a7cf | ||
|
|
aef7a6ec44 | ||
|
|
6192d24235 | ||
|
|
24fe7286fc | ||
|
|
991c121b57 | ||
|
|
23ec18e3e4 | ||
|
|
500ddc94c7 | ||
|
|
bbd8b04012 | ||
|
|
bb1b6b42e2 | ||
|
|
8e71074e1c | ||
|
|
ff0deedca9 | ||
|
|
4bb90add1d | ||
|
|
44ec05f79b | ||
|
|
7844b79274 | ||
|
|
ea75295bb3 | ||
|
|
d2c643eb0b | ||
|
|
94fcb0e9f9 | ||
|
|
3362d6b948 |
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '10.1.58'
|
||||
__version__ = '10.1.64'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -363,7 +363,10 @@ class PurchaseInvoice(BuyingController):
|
||||
return gl_entries
|
||||
|
||||
def make_supplier_gl_entry(self, gl_entries):
|
||||
grand_total = self.rounded_total or self.grand_total
|
||||
# Checked both rounding_adjustment and rounded_total
|
||||
# because rounded_total had value even before introcution of posting GLE based on rounded total
|
||||
grand_total = self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
|
||||
|
||||
if grand_total:
|
||||
# Didnot use base_grand_total to book rounding loss gle
|
||||
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
||||
|
||||
@@ -641,7 +641,9 @@ class SalesInvoice(SellingController):
|
||||
return gl_entries
|
||||
|
||||
def make_customer_gl_entry(self, gl_entries):
|
||||
grand_total = self.rounded_total or self.grand_total
|
||||
# Checked both rounding_adjustment and rounded_total
|
||||
# because rounded_total had value even before introcution of posting GLE based on rounded total
|
||||
grand_total = self.rounded_total if (self.rounding_adjustment and self.rounded_total) else self.grand_total
|
||||
if grand_total:
|
||||
# Didnot use base_grand_total to book rounding loss gle
|
||||
grand_total_in_company_currency = flt(grand_total * self.conversion_rate,
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %}</td>
|
||||
{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["debit_note"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||
@@ -189,15 +189,15 @@
|
||||
{% } %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"] ) %}</td>
|
||||
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %}</td>
|
||||
|
||||
{% if(!filters.show_pdc_in_print) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Paid Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["Credit Note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
||||
{%= format_currency(data[i]["paid_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable" ? format_currency(data[i]["credit_note"], data[i]["currency"]) : format_currency(data[i]["Debit Note"], data[i]["currency"]) %} </td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Outstanding Amount"], data[i]["currency"]) %}</td>
|
||||
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_pdc_in_print) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
@@ -238,4 +238,4 @@
|
||||
{% } %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-right text-muted">{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
|
||||
<p class="text-right text-muted">{{ __("Printed On ") }}{%= dateutil.str_to_user(dateutil.get_datetime_as_string()) %}</p>
|
||||
|
||||
@@ -306,19 +306,20 @@ def set_gl_entries_by_account(company, from_date, to_date, root_lft, root_rgt, f
|
||||
|
||||
additional_conditions = get_additional_conditions(from_date, ignore_closing_entries, filters)
|
||||
|
||||
accounts = frappe.db.sql_list("""select name from `tabAccount`
|
||||
where lft >= %s and rgt <= %s""", (root_lft, root_rgt))
|
||||
additional_conditions += " and account in ('{}')"\
|
||||
.format("', '".join([frappe.db.escape(d) for d in accounts]))
|
||||
|
||||
gl_entries = frappe.db.sql("""select posting_date, account, debit, credit, is_opening, fiscal_year from `tabGL Entry`
|
||||
where company=%(company)s
|
||||
{additional_conditions}
|
||||
and posting_date <= %(to_date)s
|
||||
and account in (select name from `tabAccount`
|
||||
where lft >= %(lft)s and rgt <= %(rgt)s)
|
||||
order by account, posting_date""".format(additional_conditions=additional_conditions),
|
||||
{
|
||||
"company": company,
|
||||
"from_date": from_date,
|
||||
"to_date": to_date,
|
||||
"lft": root_lft,
|
||||
"rgt": root_rgt
|
||||
},
|
||||
as_dict=True)
|
||||
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
source_link = "https://github.com/frappe/erpnext"
|
||||
source_link = "https://github.com/erpnext/foundation"
|
||||
|
||||
@@ -15,6 +15,8 @@ develop_version = '10.x.x-develop'
|
||||
|
||||
error_report_email = "support@erpnext.com"
|
||||
|
||||
docs_app = "foundation"
|
||||
|
||||
app_include_js = "assets/js/erpnext.min.js"
|
||||
app_include_css = "assets/css/erpnext.css"
|
||||
web_include_js = "assets/js/erpnext-web.min.js"
|
||||
|
||||
@@ -45,14 +45,21 @@ class Employee(NestedSet):
|
||||
self.validate_prefered_email()
|
||||
|
||||
if self.user_id:
|
||||
self.validate_for_enabled_user_id()
|
||||
self.validate_duplicate_user_id()
|
||||
self.validate_user_details()
|
||||
else:
|
||||
existing_user_id = frappe.db.get_value("Employee", self.name, "user_id")
|
||||
if existing_user_id:
|
||||
frappe.permissions.remove_user_permission(
|
||||
"Employee", self.name, existing_user_id)
|
||||
|
||||
def validate_user_details(self):
|
||||
data = frappe.db.get_value('User',
|
||||
self.user_id, ['enabled', 'user_image'], as_dict=1)
|
||||
|
||||
self.image = data.get("user_image")
|
||||
self.validate_for_enabled_user_id(data.get("enabled", 0))
|
||||
self.validate_duplicate_user_id()
|
||||
|
||||
def update_nsm_model(self):
|
||||
frappe.utils.nestedset.update_nsm(self)
|
||||
|
||||
@@ -133,10 +140,10 @@ class Employee(NestedSet):
|
||||
if self.status == 'Left' and not self.relieving_date:
|
||||
throw(_("Please enter relieving date."))
|
||||
|
||||
def validate_for_enabled_user_id(self):
|
||||
def validate_for_enabled_user_id(self, enabled):
|
||||
if not self.status == 'Active':
|
||||
return
|
||||
enabled = frappe.db.get_value("User", self.user_id, "enabled")
|
||||
|
||||
if enabled is None:
|
||||
frappe.throw(_("User {0} does not exist").format(self.user_id))
|
||||
if enabled == 0:
|
||||
|
||||
@@ -224,10 +224,11 @@ class ExpenseClaim(AccountsController):
|
||||
self.total_advance_amount += flt(d.allocated_amount)
|
||||
|
||||
if self.total_advance_amount:
|
||||
if flt(self.total_advance_amount) > flt(self.total_claimed_amount):
|
||||
precision = self.precision("total_advance_amount")
|
||||
if flt(self.total_advance_amount, precision) > flt(self.total_claimed_amount, precision):
|
||||
frappe.throw(_("Total advance amount cannot be greater than total claimed amount"))
|
||||
if self.total_sanctioned_amount \
|
||||
and flt(self.total_advance_amount) > flt(self.total_sanctioned_amount):
|
||||
and flt(self.total_advance_amount, precision) > flt(self.total_sanctioned_amount, precision):
|
||||
frappe.throw(_("Total advance amount cannot be greater than total sanctioned amount"))
|
||||
|
||||
def validate_sanctioned_amount(self):
|
||||
|
||||
@@ -354,7 +354,8 @@ class BOM(WebsiteGenerator):
|
||||
bom_list = self.traverse_tree(bom_list)
|
||||
for bom in bom_list:
|
||||
bom_obj = frappe.get_doc("BOM", bom)
|
||||
bom_obj.on_update()
|
||||
bom_obj.check_recursion()
|
||||
bom_obj.update_exploded_items()
|
||||
|
||||
return bom_list
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ class BOMUpdateTool(Document):
|
||||
bom_list.append(d[0])
|
||||
self.get_parent_boms(d[0], bom_list)
|
||||
|
||||
return bom_list
|
||||
return list(set(bom_list))
|
||||
|
||||
@frappe.whitelist()
|
||||
def enqueue_replace_bom(args):
|
||||
|
||||
@@ -505,4 +505,5 @@ erpnext.patches.v10_0.update_status_in_purchase_receipt
|
||||
erpnext.patches.v10_0.update_address_template_for_india
|
||||
erpnext.patches.v10_0.set_discount_amount
|
||||
erpnext.patches.v10_0.recalculate_gross_margin_for_project
|
||||
erpnext.patches.v10_0.delete_hub_documents
|
||||
erpnext.patches.v10_0.delete_hub_documents
|
||||
erpnext.patches.v10_0.update_user_image_in_employee
|
||||
19
erpnext/patches/v10_0/update_user_image_in_employee.py
Normal file
19
erpnext/patches/v10_0/update_user_image_in_employee.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# Copyright (c) 2017, Frappe and Contributors
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
|
||||
def execute():
|
||||
frappe.reload_doc('hr', 'doctype', 'employee')
|
||||
|
||||
frappe.db.sql("""
|
||||
UPDATE
|
||||
`tabEmployee`, `tabUser`
|
||||
SET
|
||||
`tabEmployee`.image = `tabUser`.user_image
|
||||
WHERE
|
||||
`tabEmployee`.user_id = `tabUser`.name and
|
||||
`tabEmployee`.user_id is not null and
|
||||
`tabEmployee`.user_id != '' and `tabEmployee`.image is null
|
||||
""")
|
||||
@@ -73,7 +73,7 @@
|
||||
{% for(var j=i*3; j
|
||||
<(i+1)*3; j++) { %} <button type="button" class="btn btn-default numeric-keypad" val="{{j+1}}">{{j+1}}</button>
|
||||
{% } %}
|
||||
<button type="button" {% if((!allow_user_to_edit_rate && chartData[i] == __("Price")) || (!allow_user_to_edit_discount && chartData[i] == __("Disc"))) { %} disabled {% } %} id="pos-item-{{ chartData[i].toLowerCase() }}" class="btn text-center btn-default numeric-keypad pos-operation">{{ __(chartData[i]) }}</button>
|
||||
<button type="button" {% if((!allow_user_to_edit_rate && __(chartData[i]) == __("Price")) || (!allow_user_to_edit_discount && __(chartData[i]) == __("Disc"))) { %} disabled {% } %} id="pos-item-{{ chartData[i].toLowerCase() }}" class="btn text-center btn-default numeric-keypad pos-operation">{{ __(chartData[i]) }}</button>
|
||||
</div>
|
||||
{% } %}
|
||||
<div class="row text-right">
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import msgprint, _
|
||||
from frappe.utils import flt
|
||||
from erpnext import get_company_currency
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
@@ -14,12 +15,14 @@ def execute(filters=None):
|
||||
item_details = get_item_details()
|
||||
data = []
|
||||
|
||||
company_currency = get_company_currency(filters["company"])
|
||||
|
||||
for d in entries:
|
||||
if d.stock_qty > 0 or filters.get('show_return_entries', 0):
|
||||
data.append([
|
||||
d.name, d.customer, d.territory, d.posting_date, d.item_code,
|
||||
d.name, d.customer, d.territory, d.warehouse, d.posting_date, d.item_code,
|
||||
item_details.get(d.item_code, {}).get("item_group"), item_details.get(d.item_code, {}).get("brand"),
|
||||
d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt
|
||||
d.stock_qty, d.base_net_amount, d.sales_person, d.allocated_percentage, d.contribution_amt, company_currency
|
||||
])
|
||||
|
||||
if data:
|
||||
@@ -32,12 +35,105 @@ def get_columns(filters):
|
||||
if not filters.get("doc_type"):
|
||||
msgprint(_("Please select the document type first"), raise_exception=1)
|
||||
|
||||
return [filters["doc_type"] + ":Link/" + filters["doc_type"] + ":140",
|
||||
_("Customer") + ":Link/Customer:140", _("Territory") + ":Link/Territory:100", _("Posting Date") + ":Date:100",
|
||||
_("Item Code") + ":Link/Item:120", _("Item Group") + ":Link/Item Group:120",
|
||||
_("Brand") + ":Link/Brand:120", _("Qty") + ":Float:100", _("Amount") + ":Currency:120",
|
||||
_("Sales Person") + ":Link/Sales Person:140", _("Contribution %") + "::110",
|
||||
_("Contribution Amount") + ":Currency:140"]
|
||||
columns = [
|
||||
{
|
||||
"label": _(filters["doc_type"]),
|
||||
"options": filters["doc_type"],
|
||||
"fieldname": frappe.scrub(filters['doc_type']),
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Customer"),
|
||||
"options": "Customer",
|
||||
"fieldname": "customer",
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Territory"),
|
||||
"options": "Territory",
|
||||
"fieldname": "territory",
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Warehouse"),
|
||||
"options": "Warehouse",
|
||||
"fieldname": "warehouse",
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Posting Date"),
|
||||
"fieldname": "posting_date",
|
||||
"fieldtype": "Date",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Item Code"),
|
||||
"options": "Item",
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Item Group"),
|
||||
"options": "Item Group",
|
||||
"fieldname": "item_group",
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Brand"),
|
||||
"options": "Brand",
|
||||
"fieldname": "brand",
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Qty"),
|
||||
"fieldname": "qty",
|
||||
"fieldtype": "Float",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Amount"),
|
||||
"options": "currency",
|
||||
"fieldname": "amount",
|
||||
"fieldtype": "Currency",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Sales Person"),
|
||||
"options": "Sales Person",
|
||||
"fieldname": "sales_person",
|
||||
"fieldtype": "Link",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Contribution %"),
|
||||
"fieldname": "contribution",
|
||||
"fieldtype": "Float",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label": _("Contribution Amount"),
|
||||
"options": "currency",
|
||||
"fieldname": "contribution_amt",
|
||||
"fieldtype": "Currency",
|
||||
"width": 140
|
||||
},
|
||||
{
|
||||
"label":_("Currency"),
|
||||
"options": "Currency",
|
||||
"fieldname":"currency",
|
||||
"fieldtype":"Link",
|
||||
"hidden" : 1
|
||||
}
|
||||
]
|
||||
|
||||
return columns
|
||||
|
||||
def get_entries(filters):
|
||||
date_field = filters["doc_type"] == "Sales Order" and "transaction_date" or "posting_date"
|
||||
@@ -48,10 +144,10 @@ def get_entries(filters):
|
||||
conditions, values = get_conditions(filters, date_field)
|
||||
|
||||
entries = frappe.db.sql("""
|
||||
select
|
||||
SELECT
|
||||
dt.name, dt.customer, dt.territory, dt.%s as posting_date, dt_item.item_code,
|
||||
st.sales_person, st.allocated_percentage,
|
||||
CASE
|
||||
st.sales_person, st.allocated_percentage, dt_item.warehouse,
|
||||
CASE
|
||||
WHEN dt.status = "Closed" THEN dt_item.%s * dt_item.conversion_factor
|
||||
ELSE dt_item.stock_qty
|
||||
END as stock_qty,
|
||||
@@ -63,9 +159,9 @@ def get_entries(filters):
|
||||
WHEN dt.status = "Closed" THEN ((dt_item.base_net_rate * dt_item.%s * dt_item.conversion_factor) * st.allocated_percentage/100)
|
||||
ELSE dt_item.base_net_amount * st.allocated_percentage/100
|
||||
END as contribution_amt
|
||||
from
|
||||
FROM
|
||||
`tab%s` dt, `tab%s Item` dt_item, `tabSales Team` st
|
||||
where
|
||||
WHERE
|
||||
st.parent = dt.name and dt.name = dt_item.parent and st.parenttype = %s
|
||||
and dt.docstatus = 1 %s order by st.sales_person, dt.name desc
|
||||
""" %(date_field, qty_field, qty_field, qty_field, filters["doc_type"], filters["doc_type"], '%s', conditions),
|
||||
@@ -115,7 +211,7 @@ def get_items(filters):
|
||||
|
||||
def get_item_details():
|
||||
item_details = {}
|
||||
for d in frappe.db.sql("""select name, item_group, brand from `tabItem`""", as_dict=1):
|
||||
for d in frappe.db.sql("""SELECT `name`, `item_group`, `brand` FROM `tabItem`""", as_dict=1):
|
||||
item_details.setdefault(d.name, d)
|
||||
|
||||
return item_details
|
||||
|
||||
@@ -255,13 +255,13 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){
|
||||
var dn_item_fields = frappe.meta.docfield_map['Delivery Note Item'];
|
||||
var dn_fields_copy = dn_fields;
|
||||
var dn_item_fields_copy = dn_item_fields;
|
||||
|
||||
if (doc.print_without_amount) {
|
||||
dn_fields['currency'].print_hide = 1;
|
||||
dn_item_fields['rate'].print_hide = 1;
|
||||
dn_item_fields['discount_percentage'].print_hide = 1;
|
||||
dn_item_fields['price_list_rate'].print_hide = 1;
|
||||
dn_item_fields['amount'].print_hide = 1;
|
||||
dn_item_fields['discount_amount'].print_hide = 1;
|
||||
dn_fields['taxes'].print_hide = 1;
|
||||
} else {
|
||||
if (dn_fields_copy['currency'].print_hide != 1)
|
||||
@@ -270,6 +270,8 @@ erpnext.stock.delivery_note.set_print_hide = function(doc, cdt, cdn){
|
||||
dn_item_fields['rate'].print_hide = 0;
|
||||
if (dn_item_fields_copy['amount'].print_hide != 1)
|
||||
dn_item_fields['amount'].print_hide = 0;
|
||||
if (dn_item_fields_copy['discount_amount'].print_hide != 1)
|
||||
dn_item_fields['discount_amount'].print_hide = 0;
|
||||
if (dn_fields_copy['taxes'].print_hide != 1)
|
||||
dn_fields['taxes'].print_hide = 0;
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ class DeliveryNote(SellingController):
|
||||
item_meta = frappe.get_meta("Delivery Note Item")
|
||||
print_hide_fields = {
|
||||
"parent": ["grand_total", "rounded_total", "in_words", "currency", "total", "taxes"],
|
||||
"items": ["rate", "amount", "price_list_rate", "discount_percentage"]
|
||||
"items": ["rate", "amount", "discount_amount", "price_list_rate", "discount_percentage"]
|
||||
}
|
||||
|
||||
for key, fieldname in print_hide_fields.items():
|
||||
|
||||
@@ -13,12 +13,18 @@ def execute(filters=None):
|
||||
def get_columns():
|
||||
return [
|
||||
{
|
||||
"label": _("Item Name"),
|
||||
"fieldname": "item_name",
|
||||
"label": _("Item Code"),
|
||||
"fieldname": "item_code",
|
||||
"fieldtype": "Link",
|
||||
"options": "Item",
|
||||
"width": 120
|
||||
},
|
||||
{
|
||||
"label": _("Item Name"),
|
||||
"fieldname": "item_name",
|
||||
"fieldtype": "Data",
|
||||
"width": 120
|
||||
},
|
||||
{
|
||||
"label": _("Warehouse"),
|
||||
"fieldname": "warehouse",
|
||||
@@ -70,7 +76,7 @@ def get_item_price_qty_data(filters):
|
||||
if filters.get("item_code"):
|
||||
conditions += "where a.item_code=%(item_code)s"
|
||||
|
||||
item_results = frappe.db.sql("""select a.item_code as item_name, a.name as price_list_name,
|
||||
item_results = frappe.db.sql("""select a.item_code, a.item_name, a.name as price_list_name,
|
||||
b.warehouse as warehouse, b.actual_qty as actual_qty
|
||||
from `tabItem Price` a left join `tabBin` b
|
||||
ON a.item_code = b.item_code
|
||||
@@ -86,6 +92,7 @@ def get_item_price_qty_data(filters):
|
||||
if item_results:
|
||||
for item_dict in item_results:
|
||||
data = {
|
||||
'item_code': item_dict.item_code,
|
||||
'item_name': item_dict.item_name,
|
||||
'warehouse': item_dict.warehouse,
|
||||
'stock_available': item_dict.actual_qty or 0,
|
||||
|
||||
Reference in New Issue
Block a user