Merge branch 'develop' into version-12

This commit is contained in:
Sahil Khan 2019-09-24 18:16:53 +05:30
commit 6211a5bc3b
39 changed files with 268 additions and 1244 deletions

View File

@ -5,7 +5,7 @@ import frappe
from erpnext.hooks import regional_overrides
from frappe.utils import getdate
__version__ = '12.1.4'
__version__ = '12.1.5'
def get_default_company(user=None):
'''Get default company for user'''

View File

@ -9,12 +9,11 @@ def get_data():
'non_standard_fieldnames': {
'Customer': 'default_bank_account',
'Supplier': 'default_bank_account',
'Journal Entry': 'bank_account_no'
},
'transactions': [
{
'label': _('Payments'),
'items': ['Payment Entry', 'Payment Request', 'Payment Order']
'items': ['Payment Entry', 'Payment Request', 'Payment Order', 'Payroll Entry']
},
{
'label': _('Party'),

View File

@ -7,7 +7,7 @@ frappe.provide("erpnext.journal_entry");
frappe.ui.form.on("Journal Entry", {
setup: function(frm) {
frm.add_fetch("bank_account_no", "account", "account");
frm.add_fetch("bank_account", "account", "account");
},
refresh: function(frm) {

View File

@ -10,7 +10,7 @@
"account_type",
"balance",
"col_break1",
"bank_account_no",
"bank_account",
"party_type",
"party",
"party_balance",
@ -89,12 +89,6 @@
"fieldname": "col_break1",
"fieldtype": "Column Break"
},
{
"fieldname": "bank_account_no",
"fieldtype": "Link",
"label": "Bank Account No",
"options": "Bank Account"
},
{
"fieldname": "party_type",
"fieldtype": "Link",
@ -266,11 +260,17 @@
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
},
{
"fieldname": "bank_account",
"fieldtype": "Link",
"label": "Bank Account",
"options": "Bank Account"
}
],
"idx": 1,
"istable": 1,
"modified": "2019-07-16 17:12:08.238334",
"modified": "2019-09-12 12:16:17.588399",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Journal Entry Account",

View File

@ -12,7 +12,7 @@ from frappe.utils import (add_days, getdate, formatdate, date_diff,
from frappe.contacts.doctype.address.address import (get_address_display,
get_default_address, get_company_address)
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
from erpnext.exceptions import PartyFrozen, InvalidAccountCurrency
from erpnext.accounts.utils import get_fiscal_year
from erpnext import get_company_currency
@ -446,9 +446,7 @@ def validate_party_frozen_disabled(party_type, party_name):
if party_type and party_name:
if party_type in ("Customer", "Supplier"):
party = frappe.get_cached_value(party_type, party_name, ["is_frozen", "disabled"], as_dict=True)
if party.disabled:
frappe.throw(_("{0} {1} is disabled").format(party_type, party_name), PartyDisabled)
elif party.get("is_frozen"):
if party.get("is_frozen"):
frozen_accounts_modifier = frappe.db.get_single_value( 'Accounts Settings', 'frozen_accounts_modifier')
if not frozen_accounts_modifier in frappe.get_roles():
frappe.throw(_("{0} {1} is frozen").format(party_type, party_name), PartyFrozen)

View File

@ -17,7 +17,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
filters.update({"from_date": filters.get("date_range") and filters.get("date_range")[0], "to_date": filters.get("date_range") and filters.get("date_range")[1]})
columns = get_columns(additional_table_columns)
company_currency = erpnext.get_company_currency(filters.get('company'))
company_currency = frappe.get_cached_value('Company', filters.get("company"), "default_currency")
item_list = get_items(filters, additional_query_columns)
if item_list:

View File

@ -68,7 +68,8 @@ def _execute(filters, additional_table_columns=None, additional_query_columns=No
total_tax = 0
for tax_acc in tax_accounts:
if tax_acc not in income_accounts:
tax_amount = flt(invoice_tax_map.get(inv.name, {}).get(tax_acc))
tax_amount_precision = get_field_precision(frappe.get_meta("Sales Taxes and Charges").get_field("tax_amount"), currency=company_currency) or 2
tax_amount = flt(invoice_tax_map.get(inv.name, {}).get(tax_acc), tax_amount_precision)
total_tax += tax_amount
row.append(tax_amount)

View File

@ -5,9 +5,8 @@
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Capital Traders",
"modified": "2018-12-12 05:10:02.987274",
"is_standard": "Yes",
"modified": "2019-02-12 05:10:02.987274",
"modified_by": "Administrator",
"module": "Accounts",
"name": "Supplier Ledger Summary",

View File

@ -6,8 +6,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2018-08-21 11:25:00.551823",
"modified": "2018-09-21 11:25:00.551823",
"modified_by": "Administrator",
"module": "Accounts",
"name": "TDS Computation Summary",

View File

@ -6,8 +6,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2018-08-21 11:33:40.804532",
"modified": "2019-09-24 13:46:16.473711",
"modified_by": "Administrator",
"module": "Accounts",
"name": "TDS Payable Monthly",

View File

@ -5,7 +5,6 @@ from __future__ import unicode_literals
import frappe, unittest
from erpnext.accounts.party import get_due_date
from erpnext.exceptions import PartyDisabled
from frappe.test_runner import make_test_records
test_dependencies = ['Payment Term', 'Payment Terms Template']
@ -71,7 +70,7 @@ class TestSupplier(unittest.TestCase):
po = create_purchase_order(do_not_save=True)
self.assertRaises(PartyDisabled, po.save)
self.assertRaises(frappe.ValidationError, po.save)
frappe.db.set_value("Supplier", "_Test Supplier", "disabled", 0)

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "",
"modified": "2017-04-17 00:20:27.248275",
"modified": "2019-04-17 00:20:27.248275",
"modified_by": "Administrator",
"module": "CRM",
"name": "Campaign Efficiency",

View File

@ -6,8 +6,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "",
"modified": "2018-09-17 14:40:52.035394",
"modified": "2019-09-19 14:40:52.035394",
"modified_by": "Administrator",
"module": "CRM",
"name": "Lead Conversion Time",

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Shishuvan Secondary School",
"modified": "2018-02-08 15:11:35.339434",
"modified": "2019-02-08 15:11:35.339434",
"modified_by": "Administrator",
"module": "Education",
"name": "Final Assessment Grades",

View File

@ -5,4 +5,3 @@ import frappe
class PartyFrozen(frappe.ValidationError): pass
class InvalidAccountCurrency(frappe.ValidationError): pass
class InvalidCurrency(frappe.ValidationError): pass
class PartyDisabled(frappe.ValidationError):pass

File diff suppressed because it is too large Load Diff

View File

@ -37,8 +37,9 @@
"cost_center",
"account",
"payment_account",
"section_break2",
"amended_from",
"column_break_33",
"bank_account",
"salary_slips_created",
"salary_slips_submitted"
],
@ -206,15 +207,12 @@
{
"allow_on_submit": 1,
"description": "Select Payment Account to make Bank Entry",
"fetch_from": "bank_account.account",
"fieldname": "payment_account",
"fieldtype": "Link",
"label": "Payment Account",
"options": "Account"
},
{
"fieldname": "section_break2",
"fieldtype": "Section Break"
},
{
"fieldname": "amended_from",
"fieldtype": "Link",
@ -248,11 +246,21 @@
{
"fieldname": "dimension_col_break",
"fieldtype": "Column Break"
},
{
"fieldname": "bank_account",
"fieldtype": "Link",
"label": "Bank Account",
"options": "Bank Account"
},
{
"fieldname": "column_break_33",
"fieldtype": "Column Break"
}
],
"icon": "fa fa-cog",
"is_submittable": 1,
"modified": "2019-05-25 22:47:49.977955",
"modified": "2019-09-12 15:46:31.436381",
"modified_by": "Administrator",
"module": "HR",
"name": "Payroll Entry",

View File

@ -39,7 +39,7 @@ class PayrollEntry(Document):
and for which salary structure exists
"""
cond = self.get_filter_condition()
cond += self.get_joining_releiving_condition()
cond += self.get_joining_relieving_condition()
condition = ''
if self.payroll_frequency:
@ -93,7 +93,7 @@ class PayrollEntry(Document):
return cond
def get_joining_releiving_condition(self):
def get_joining_relieving_condition(self):
cond = """
and ifnull(t1.date_of_joining, '0000-00-00') <= '%(end_date)s'
and ifnull(t1.relieving_date, '2199-12-31') >= '%(start_date)s'
@ -341,6 +341,7 @@ class PayrollEntry(Document):
journal_entry.set("accounts", [
{
"account": self.payment_account,
"bank_account": self.bank_account,
"credit_in_account_currency": payment_amount
},
{

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-26 16:57:52.558895",
"modified": "2019-04-26 16:57:52.558895",
"modified_by": "Administrator",
"module": "HR",
"name": "Bank Remittance",

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "sapcon-old",
"modified": "2019-09-05 11:18:06.209397",
"modified": "2019-09-06 11:18:06.209397",
"modified_by": "Administrator",
"module": "HR",
"name": "Employee Leave Balance Summary",

View File

@ -6,8 +6,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2018-05-28 16:22:24.040106",
"modified": "2018-06-28 16:22:24.040106",
"modified_by": "Administrator",
"module": "Manufacturing",
"name": "BOM Variance Report",

View File

@ -635,4 +635,5 @@ erpnext.patches.v12_0.remove_bank_remittance_custom_fields
erpnext.patches.v12_0.generate_leave_ledger_entries
erpnext.patches.v12_0.move_credit_limit_to_customer_credit_limit
erpnext.patches.v12_0.add_variant_of_in_item_attribute_table
erpnext.patches.v12_0.create_default_energy_point_rules
erpnext.patches.v12_0.rename_bank_account_field_in_journal_entry_account
erpnext.patches.v12_0.create_default_energy_point_rules

View File

@ -0,0 +1,17 @@
# Copyright (c) 2019, Frappe and Contributors
# License: GNU General Public License v3. See license.txt
from __future__ import unicode_literals
import frappe
from frappe.model.utils.rename_field import rename_field
def execute():
''' Change the fieldname from bank_account_no to bank_account '''
if not frappe.get_meta("Journal Entry Account").has_field("bank_account"):
frappe.reload_doc("Accounts", "doctype", "Journal Entry Account")
update_journal_entry_account_fieldname()
def update_journal_entry_account_fieldname():
''' maps data from old field to the new field '''
if frappe.db.has_column('Journal Entry Account', 'bank_account_no'):
rename_field("Journal Entry Account", "bank_account_no", "bank_account")

View File

@ -2,6 +2,7 @@ frappe.provide('frappe.ui.form');
frappe.ui.form.CustomerQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({
init: function(doctype, after_insert) {
this.skip_redirect_on_error = true;
this._super(doctype, after_insert);
},
@ -37,8 +38,7 @@ frappe.ui.form.CustomerQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({
{
label: __("Address Line 1"),
fieldname: "address_line1",
fieldtype: "Data",
reqd: 1
fieldtype: "Data"
},
{
label: __("Address Line 2"),
@ -56,8 +56,7 @@ frappe.ui.form.CustomerQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({
{
label: __("City"),
fieldname: "city",
fieldtype: "Data",
reqd: 1,
fieldtype: "Data"
},
{
label: __("State"),
@ -68,8 +67,7 @@ frappe.ui.form.CustomerQuickEntryForm = frappe.ui.form.QuickEntryForm.extend({
label: __("Country"),
fieldname: "country",
fieldtype: "Link",
options: "Country",
reqd: 1
options: "Country"
},
{
label: __("Customer POS Id"),

View File

@ -6,8 +6,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Standard",
"modified": "2018-04-26 12:59:38.603649",
"modified": "2019-04-26 12:59:38.603649",
"modified_by": "Administrator",
"module": "Regional",
"name": "HSN-wise-summary of outward supplies",

View File

@ -357,6 +357,16 @@ def make_contact(args, is_primary_contact=1):
return contact
def make_address(args, is_primary_address=1):
reqd_fields = []
for field in ['city', 'country']:
if not args.get(field):
reqd_fields.append( '<li>' + field.title() + '</li>')
if reqd_fields:
msg = _("Following fields are mandatory to create address:")
frappe.throw("{0} <br><br> <ul>{1}</ul>".format(msg, '\n'.join(reqd_fields)),
title = _("Missing Values Required"))
address = frappe.get_doc({
'doctype': 'Address',
'address_title': args.get('name'),

View File

@ -8,7 +8,7 @@ import unittest
from erpnext.accounts.party import get_due_date
from frappe.test_runner import make_test_records
from erpnext.exceptions import PartyFrozen, PartyDisabled
from erpnext.exceptions import PartyFrozen
from frappe.utils import flt
from erpnext.selling.doctype.customer.customer import get_credit_limit, get_customer_outstanding
from erpnext.tests.utils import create_test_contact_and_address
@ -178,7 +178,7 @@ class TestCustomer(unittest.TestCase):
so = make_sales_order(do_not_save=True)
self.assertRaises(PartyDisabled, so.save)
self.assertRaises(frappe.ValidationError, so.save)
frappe.db.set_value("Customer", "_Test Customer", "disabled", 0)

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Delta9",
"modified": "2019-06-12 03:25:36.263179",
"modified": "2019-06-14 03:25:36.263179",
"modified_by": "Administrator",
"module": "Selling",
"name": "Customer-wise Item Price",

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-15 15:22:15.012318",
"modified": "2019-04-15 15:22:15.012318",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Partner Commission Summary",

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-25 18:22:37.323995",
"modified": "2019-04-25 18:22:37.323995",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Partner Target Variance based on Item Group",

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-25 18:15:09.920739",
"modified": "2019-04-25 18:15:09.920739",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Partner Transaction Summary",

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-25 22:16:49.040998",
"modified": "2019-04-25 22:16:49.040998",
"modified_by": "Administrator",
"module": "Selling",
"name": "Sales Person Target Variance Based On Item Group",

View File

@ -7,8 +7,7 @@
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"letter_head": "Gadgets International",
"modified": "2019-03-25 22:20:59.033199",
"modified": "2019-04-25 22:20:59.033199",
"modified_by": "Administrator",
"module": "Selling",
"name": "Territory Target Variance Based On Item Group",

View File

@ -15,12 +15,17 @@ class LandedCostVoucher(Document):
for pr in self.get("purchase_receipts"):
if pr.receipt_document_type and pr.receipt_document:
pr_items = frappe.db.sql("""select pr_item.item_code, pr_item.description,
pr_item.qty, pr_item.base_rate, pr_item.base_amount, pr_item.name, pr_item.cost_center
pr_item.qty, pr_item.base_rate, pr_item.base_amount, pr_item.name,
pr_item.cost_center, pr_item.asset
from `tab{doctype} Item` pr_item where parent = %s
and exists(select name from tabItem where name = pr_item.item_code and is_stock_item = 1)
and exists(select name from tabItem
where name = pr_item.item_code and (is_stock_item = 1 or is_fixed_asset=1))
""".format(doctype=pr.receipt_document_type), pr.receipt_document, as_dict=True)
for d in pr_items:
if d.asset and frappe.db.get_value("Asset", d.asset, 'docstatus') == 1:
continue
item = self.append("items")
item.item_code = d.item_code
item.description = d.description

View File

@ -20,7 +20,7 @@ def get_product_bundle_items(item_code):
def get_packing_item_details(item, company):
return frappe.db.sql("""
select i.item_name, i.description, i.stock_uom, id.default_warehouse
select i.item_name, i.is_stock_item, i.description, i.stock_uom, id.default_warehouse
from `tabItem` i LEFT JOIN `tabItem Default` id ON id.parent=i.name and id.company=%s
where i.name = %s""",
(company, item), as_dict = 1)[0]
@ -30,7 +30,7 @@ def get_bin_qty(item, warehouse):
where item_code = %s and warehouse = %s""", (item, warehouse), as_dict = 1)
return det and det[0] or frappe._dict()
def update_packing_list_item(doc, packing_item_code, qty, main_item_row, description):
def update_packing_list_item(doc, packing_item_code, qty, main_item_row, description):
item = get_packing_item_details(packing_item_code, doc.company)
# check if exists
@ -53,7 +53,7 @@ def update_packing_list_item(doc, packing_item_code, qty, main_item_row, descrip
if description and not pi.description:
pi.description = description
if not pi.warehouse:
pi.warehouse = (main_item_row.warehouse if ((doc.get('is_pos')
pi.warehouse = (main_item_row.warehouse if ((doc.get('is_pos') or item.is_stock_item \
or not item.default_warehouse) and main_item_row.warehouse) else item.default_warehouse)
if not pi.batch_no:
@ -108,8 +108,8 @@ def get_items_from_product_bundle(args):
"qty": flt(args["quantity"]) * flt(item.qty)
})
items.append(get_item_details(args))
return items
def on_doctype_update():
frappe.db.add_index("Packed Item", ["item_code", "warehouse"])

View File

@ -15,6 +15,7 @@ from frappe.desk.notifications import clear_doctype_notifications
from frappe.model.mapper import get_mapped_doc
from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_disabled
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
from six import iteritems
form_grid_templates = {
@ -278,8 +279,7 @@ class PurchaseReceipt(BuyingController):
d.rejected_warehouse not in warehouse_with_no_account:
warehouse_with_no_account.append(d.warehouse)
if not is_cwip_accounting_disabled():
self.get_asset_gl_entry(gl_entries)
self.get_asset_gl_entry(gl_entries, expenses_included_in_valuation)
# Cost center-wise amount breakup for other charges included for valuation
valuation_tax = {}
for tax in self.get("taxes"):
@ -333,15 +333,24 @@ class PurchaseReceipt(BuyingController):
return process_gl_map(gl_entries)
def get_asset_gl_entry(self, gl_entries):
def get_asset_gl_entry(self, gl_entries, expenses_included_in_valuation=None):
arbnb_account, cwip_account = None, None
cwip_disabled = is_cwip_accounting_disabled()
if not expenses_included_in_valuation:
expenses_included_in_valuation = self.get_company_default("expenses_included_in_valuation")
for d in self.get("items"):
if d.is_fixed_asset:
if d.is_fixed_asset and not (arbnb_account and cwip_account):
arbnb_account = self.get_company_default("asset_received_but_not_billed")
# CWIP entry
cwip_account = get_asset_account("capital_work_in_progress_account", d.asset,
company = self.company)
if d.is_fixed_asset and not cwip_disabled:
asset_amount = flt(d.net_amount) + flt(d.item_tax_amount/self.conversion_rate)
base_asset_amount = flt(d.base_net_amount + d.item_tax_amount)
@ -368,6 +377,36 @@ class PurchaseReceipt(BuyingController):
if asset_rbnb_currency == self.company_currency else asset_amount)
}, item=d))
if d.is_fixed_asset and flt(d.landed_cost_voucher_amount):
asset_account = (get_asset_category_account(d.asset, 'fixed_asset_account',
company = self.company) if cwip_disabled else cwip_account)
gl_entries.append(self.get_gl_dict({
"account": expenses_included_in_valuation,
"against": asset_account,
"cost_center": d.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"credit": flt(d.landed_cost_voucher_amount),
"project": d.project
}, item=d))
gl_entries.append(self.get_gl_dict({
"account": asset_account,
"against": expenses_included_in_valuation,
"cost_center": d.cost_center,
"remarks": self.get("remarks") or _("Accounting Entry for Stock"),
"debit": flt(d.landed_cost_voucher_amount),
"project": d.project
}, item=d))
if d.asset:
doc = frappe.get_doc("Asset", d.asset)
frappe.db.set_value("Asset", d.asset, "gross_purchase_amount",
doc.gross_purchase_amount + flt(d.landed_cost_voucher_amount))
frappe.db.set_value("Asset", d.asset, "purchase_receipt_amount",
doc.purchase_receipt_amount + flt(d.landed_cost_voucher_amount))
return gl_entries
def update_status(self, status):

View File

@ -254,7 +254,7 @@ class StockEntry(StockController):
target_mandatory = ["Material Receipt", "Material Transfer", "Send to Subcontractor",
"Material Transfer for Manufacture", "Send to Warehouse", "Receive at Warehouse"]
validate_for_manufacture_repack = any([d.bom_no for d in self.get("items")])
validate_for_manufacture = any([d.bom_no for d in self.get("items")])
if self.purpose in source_mandatory and self.purpose not in target_mandatory:
self.to_warehouse = None
@ -285,8 +285,8 @@ class StockEntry(StockController):
else:
frappe.throw(_("Target warehouse is mandatory for row {0}").format(d.idx))
if self.purpose in ["Manufacture", "Repack"]:
if validate_for_manufacture_repack:
if self.purpose == "Manufacture":
if validate_for_manufacture:
if d.bom_no:
d.s_warehouse = None

View File

@ -0,0 +1,34 @@
{
"add_total_row": 0,
"creation": "2019-09-16 14:10:33.102865",
"disable_prepared_report": 0,
"disabled": 0,
"docstatus": 0,
"doctype": "Report",
"idx": 0,
"is_standard": "Yes",
"modified": "2019-09-21 15:19:55.710578",
"modified_by": "Administrator",
"module": "Stock",
"name": "Purchase Order Items To Be Received or Billed",
"owner": "Administrator",
"prepared_report": 0,
"query": "SELECT\n\t`poi_pri`.`purchase_order` as \"Purchase Order:Link/Purchase Order:120\",\n\t`poi_pri`.`status` as \"Status:Data:120\",\n\t`poi_pri`.`transaction_date` as \"Date:Date:100\",\n\t`poi_pri`.`schedule_date` as \"Reqd by Date:Date:110\",\n\t`poi_pri`.`supplier` as \"Supplier:Link/Supplier:120\",\n\t`poi_pri`.`supplier_name` as \"Supplier Name::150\",\n\t`poi_pri`.`item_code` as \"Item Code:Link/Item:120\",\n\t`poi_pri`.`qty` as \"Qty:Float:100\",\n\t`poi_pri`.`base_amount` as \"Base Amount:Currency:100\",\n\t`poi_pri`.`received_qty` as \"Received Qty:Float:100\",\n\t`poi_pri`.`received_amount` as \"Received Qty Amount:Currency:100\",\n\t`poi_pri`.`qty_to_receive` as \"Qty to Receive:Float:100\",\n\t`poi_pri`.`amount_to_be_received` as \"Amount to Receive:Currency:100\",\n\t`poi_pri`.`billed_amount` as \"Billed Amount:Currency:100\",\n\t`poi_pri`.`amount_to_be_billed` as \"Amount To Be Billed:Currency:100\",\n\tSUM(`pii`.`qty`) AS \"Billed Qty:Float:100\",\n\t`poi_pri`.qty - SUM(`pii`.`qty`) AS \"Qty To Be Billed:Float:100\",\n\t`poi_pri`.`warehouse` as \"Warehouse:Link/Warehouse:150\",\n\t`poi_pri`.`item_name` as \"Item Name::150\",\n\t`poi_pri`.`description` as \"Description::200\",\n\t`poi_pri`.`brand` as \"Brand::100\",\n\t`poi_pri`.`project` as \"Project\",\n\t`poi_pri`.`company` as \"Company:Link/Company:\"\nFROM\n\t(SELECT\n\t\t`po`.`name` AS 'purchase_order',\n\t\t`po`.`status`,\n\t\t`po`.`company`,\n\t\t`poi`.`warehouse`,\n\t\t`poi`.`brand`,\n\t\t`poi`.`description`,\n\t\t`po`.`transaction_date`,\n\t\t`poi`.`schedule_date`,\n\t\t`po`.`supplier`,\n\t\t`po`.`supplier_name`,\n\t\t`poi`.`project`,\n\t\t`poi`.`item_code`,\n\t\t`poi`.`item_name`,\n\t\t`poi`.`qty`,\n\t\t`poi`.`base_amount`,\n\t\t`poi`.`received_qty`,\n\t\t(`poi`.billed_amt * ifnull(`po`.conversion_rate, 1)) as billed_amount,\n\t\t(`poi`.base_amount - (`poi`.billed_amt * ifnull(`po`.conversion_rate, 1))) as amount_to_be_billed,\n\t\t`poi`.`qty` - IFNULL(`poi`.`received_qty`, 0) AS 'qty_to_receive',\n\t\t(`poi`.`qty` - IFNULL(`poi`.`received_qty`, 0)) * `poi`.`rate` AS 'amount_to_be_received',\n\t\tSUM(`pri`.`amount`) AS 'received_amount',\n\t\t`poi`.`name` AS 'poi_name',\n\t\t`pri`.`name` AS 'pri_name'\n\tFROM\n\t\t`tabPurchase Order` po\n\t\tLEFT JOIN `tabPurchase Order Item` poi\n\t\tON `poi`.`parent` = `po`.`name`\n\t\tLEFT JOIN `tabPurchase Receipt Item` pri\n\t\tON `pri`.`purchase_order_item` = `poi`.`name`\n\t\t\tAND `pri`.`docstatus`=1\n\tWHERE\n\t\t`po`.`status` not in ('Stopped', 'Closed')\n\t\tAND `po`.`docstatus` = 1\n\t\tAND IFNULL(`poi`.`received_qty`, 0) < IFNULL(`poi`.`qty`, 0)\n\tGROUP BY `poi`.`name`\n\tORDER BY `po`.`transaction_date` ASC\n\t) poi_pri\n\tLEFT JOIN `tabPurchase Invoice Item` pii\n\tON `pii`.`po_detail` = `poi_pri`.`poi_name`\n\t\tAND `pii`.`docstatus`=1\nGROUP BY `poi_pri`.`poi_name`",
"ref_doctype": "Purchase Order",
"report_name": "Purchase Order Items To Be Received or Billed1",
"report_type": "Query Report",
"roles": [
{
"role": "Purchase Manager"
},
{
"role": "Purchase User"
},
{
"role": "Stock User"
},
{
"role": "Stock Manager"
}
]
}