Compare commits

...

42 Commits

Author SHA1 Message Date
Sahil Khan
5889a29656 Merge branch 'v11-pre-release' into version-11 2019-10-22 17:03:12 +05:30
Sahil Khan
0e7ca6ada7 bumped to version 11.1.67 2019-10-22 17:23:12 +05:50
Anurag Mishra
5a2ea528e8 fix: if naming if item-code and index both are same (#19372) 2019-10-22 11:46:42 +05:30
Saurabh
8957093439 fix: Don't show make jv button if equity or liability account and asset account not specified (#19349) 2019-10-21 16:02:47 +05:30
Nabin Hait
507c435dee Reorder level report fix v11 (#19367)
* fix: Fixed consumed qty based on Stock Ledger Entry

* Update itemwise_recommended_reorder_level.py
2019-10-21 16:01:51 +05:30
Deepesh Garg
8889edad72 Merge pull request #19365 from deepeshgarg007/sales_return_print_fix
fix: Positive qty in sales return print
2019-10-21 15:23:34 +05:30
Nabin Hait
e27d1aebd5 fix: Positive qty in sales return print 2019-10-21 14:28:33 +05:30
Deepesh Garg
ef567eac37 fix: Item Price changes are not persistent after updating cost on submitted BOM (#19357) 2019-10-21 13:27:34 +05:30
rohitwaghchaure
f8e0a2204e Merge pull request #19331 from rohitwaghchaure/minor_loan_not_able_to_make_jv
fix: not able to save journal entry for disbursement amount
2019-10-16 19:02:09 +05:30
Rohit Waghchaure
baecc7fd31 fix: not able to save journal entry for disbursement amount 2019-10-16 18:40:27 +05:30
Deepesh Garg
675e2670b2 fix: Show Create Loan button only if loan is not created (#19291) 2019-10-14 15:50:19 +05:30
Deepesh Garg
3919fd10ad Merge pull request #19289 from deepeshgarg007/chart_fix_analytics_v11
fix: Chart fix in Analytics report when based on item
2019-10-13 09:33:16 +05:30
deepeshgarg007
b4e61e19bb fix: Chart fix in Analytics report 2019-10-12 23:11:28 +05:30
Marica
aa3d6ed11e fix: Margin and Discount percentage set correctly via 'Update Items' (#19173) 2019-10-11 11:52:29 +05:30
Nabin Hait
382735ad2f fix: Set incoming rate for standalone sales return (#19264) 2019-10-10 16:40:10 +05:30
Deepesh Garg
8d42b75e29 Merge pull request #19254 from Thunderbottom/e-invoice-disc-fix-v11
chore: check if discount_percentage exists
2019-10-06 23:47:18 +05:30
Chinmay D. Pai
7e03e046ec chore: check if discount_percentage exists
fixes TypeError: '>' not supported between instances of 'NoneType' and 'float'

Signed-off-by: Chinmay D. Pai <chinmaydpai@gmail.com>
2019-10-05 10:20:19 +05:30
Sahil Khan
bfddc8aba1 Merge branch 'version-11-hotfix' into version-11 2019-10-04 13:43:32 +05:30
Sahil Khan
d0dafcc46f bumped to version 11.1.66 2019-10-04 14:03:32 +05:50
gavin
f8996b64f1 fix: report ~ lead conversion time (#19234) 2019-10-03 11:37:41 +05:30
Rucha Mahabal
867443ea6d fix: produced_qty field hidden and not updated in sales order item (v11) (#19214)
* fix: produced_qty field hidden and not updated in sales order item

* fix: codacy review
2019-09-30 20:04:21 +05:30
Rohan
acdc230ef3 fix: set no-copy on some contract fields (#19207) 2019-09-30 20:04:03 +05:30
DeeMysterio
86232e4449 fix(purchase receipt): rename return/invoice to Purchase return/invoice (#19213) 2019-09-30 16:59:08 +05:30
rohitwaghchaure
78c7f03731 fix: mismatch stock value between stock balance report and stock in hand in trial balance (#19203) 2019-09-30 15:18:38 +05:30
Marica
65b99a5109 fix: Make '% Completed' 100% in Projects if no Tasks and Status is Completed (#19176) 2019-09-30 15:12:10 +05:30
rohitwaghchaure
8ec290d5ec fix: group by customer filter shows incorrect value in buying amount column for the gross profit report (#18998) 2019-09-30 10:28:10 +05:30
Nabin Hait
65a259eb81 refactor: Reposting utility of Stock ledger (#19153) 2019-09-26 16:44:02 +05:30
Sahil Khan
47420578ae Merge branch 'version-11-hotfix' into version-11 2019-09-26 13:55:31 +05:30
Sahil Khan
35d8cd9f10 bumped to version 11.1.65 2019-09-26 14:15:31 +05:50
Rucha Mahabal
1e55ac6a4f fix(Report): Sales Register (#19170) 2019-09-25 16:03:09 +05:30
Nabin Hait
ff7a5d18d1 fix: Handling payments against credit/debit notes and party currency (#19152) 2019-09-24 19:52:06 +05:30
Rucha Mahabal
5a15dcc060 fix(Stock): item variant description (#19135) 2019-09-24 19:16:43 +05:30
Sahil Khan
cec6c87e09 Merge branch 'version-11-hotfix' into version-11 2019-09-24 18:14:44 +05:30
Sahil Khan
b2870b9426 bumped to version 11.1.64 2019-09-24 18:34:44 +05:50
rohitwaghchaure
e27600066c Merge pull request #19145 from rohitwaghchaure/fixed_imponibileimporto_for_the_previous_row_total
fix: ImponibileImporto not getting calculated properly
2019-09-24 18:11:16 +05:30
Nabin Hait
5b8c624b34 Merge branch 'version-11-hotfix' into fixed_imponibileimporto_for_the_previous_row_total 2019-09-24 11:46:24 +05:30
Anurag Mishra
9e8531d68e fix: provided delete permission (#19142) 2019-09-24 09:55:01 +05:30
Mangesh-Khairnar
ebeb137351 chore: remove unlinked letter head references (#19139) 2019-09-24 09:52:13 +05:30
Rohit Waghchaure
8c7d28a41a fix: ImponibileImporto not getting calculated properly 2019-09-23 17:39:55 +05:30
rohitwaghchaure
d90b80af86 Merge pull request #19128 from rohitwaghchaure/removed_mandatory_property_for_address_field_in_quick_entry_v11_hotfix
fix: removed mandatory property for address field in quick entry
2019-09-23 14:48:41 +05:30
Anurag Mishra
b62e17f7f2 feat: missmatching amount in GST Sales report and itemised sales report (#19119) 2019-09-20 22:59:26 +05:30
Rohit Waghchaure
ec56984e12 fix: removed mandatory property for address field in quick entry 2019-09-20 12:20:37 +05:30
46 changed files with 2739 additions and 2506 deletions

View File

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

View File

@@ -363,7 +363,7 @@ class PurchaseInvoice(BuyingController):
update_outstanding = "No" if (cint(self.is_paid) or self.write_off_account) else "Yes"
make_gl_entries(gl_entries, cancel=(self.docstatus == 2),
update_outstanding=update_outstanding, merge_entries=False)
update_outstanding=update_outstanding, merge_entries=False, from_repost=from_repost)
if update_outstanding == "No":
update_outstanding_amt(self.credit_to, "Supplier", self.supplier,

View File

@@ -699,7 +699,7 @@ class SalesInvoice(SellingController):
cint(self.redeem_loyalty_points)) else "Yes"
make_gl_entries(gl_entries, cancel=(self.docstatus == 2),
update_outstanding=update_outstanding, merge_entries=False)
update_outstanding=update_outstanding, merge_entries=False, from_repost=from_repost)
if update_outstanding == "No":
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt

View File

@@ -16,7 +16,7 @@ frappe.ui.form.on('Share Transfer', {
};
};
});
if (frm.doc.docstatus == 1) {
if (frm.doc.docstatus == 1 && frm.doc.equity_or_liability_account && frm.doc.asset_account ) {
frm.add_custom_button(__('Make Journal Entry'), function () {
erpnext.share_transfer.make_jv(frm);
});
@@ -92,6 +92,7 @@ erpnext.share_transfer.make_jv = function (frm) {
debit_applicant_type = "Shareholder";
debit_applicant = frm.doc.from_shareholder;
}
frappe.call({
args: {
"company": frm.doc.company,

View File

@@ -292,11 +292,14 @@ def make_jv_entry( company, account, amount, payment_account,\
"party_type": debit_applicant_type,
"party": debit_applicant,
})
account_amt_list.append({
"account": payment_account,
"credit_in_account_currency": amount,
"party_type": credit_applicant_type,
"party": credit_applicant,
})
journal_entry.set("accounts", account_amt_list)
return journal_entry.as_dict()

View File

@@ -9,7 +9,7 @@
</div>
<div class="col-xs-{{ "3" if df.fieldtype=="Check" else "7" }} value">
{% if doc.get(df.fieldname) != None -%}
{{ frappe.utils.fmt_money((doc[df.fieldname])|int|abs, currency=doc.currency) }}
{{ frappe.utils.fmt_money((doc[df.fieldname])|abs, currency=doc.currency) }}
{% endif %}
</div>
</div>
@@ -26,7 +26,7 @@
<div class="col-xs-5 {%- if doc.align_labels_right %} text-right{%- endif -%}">
<label>{{ charge.get_formatted("description") }}</label></div>
<div class="col-xs-7 text-right">
{{ frappe.utils.fmt_money((charge.tax_amount)|int|abs, currency=doc.currency) }}
{{ frappe.utils.fmt_money((charge.tax_amount)|abs, currency=doc.currency) }}
</div>
</div>
{%- endif -%}
@@ -65,8 +65,10 @@
{% for tdf in visible_columns %}
{% if not d.flags.compact_item_print or tdf.fieldname in doc.get(df.fieldname)[0].flags.compact_item_fields %}
<td class="{{ get_align_class(tdf) }}" {{ fieldmeta(df) }}>
{% if tdf.fieldtype == 'Currency' %}
<div class="value">{{ frappe.utils.fmt_money((d[tdf.fieldname])|int|abs, currency=doc.currency) }}</div></td>
{% if tdf.fieldname == 'qty' %}
<div class="value">{{ (d[tdf.fieldname])|abs }}</div></td>
{% elif tdf.fieldtype == 'Currency' %}
<div class="value">{{ frappe.utils.fmt_money((d[tdf.fieldname])|abs, currency=doc.currency) }}</div></td>
{% else %}
<div class="value">{{ print_value(tdf, d, doc, visible_columns) }}</div></td>
{% endif %}
@@ -117,7 +119,7 @@
{{ render_currency(df, doc) }}
{% elif df.fieldtype =='Table' %}
{{ render_table(df, doc)}}
{% elif doc[df.fieldname] %}
{% elif doc[df.fieldname] and df.fieldname != 'total_qty' %}
{{ render_field(df, doc) }}
{% endif %}
{% endfor %}

View File

@@ -58,7 +58,6 @@ class ReceivablePayableReport(object):
self.invoices = set()
def get_data(self):
t1 = now()
self.get_gl_entries()
self.voucher_balance = OrderedDict()
self.init_voucher_balance() # invoiced, paid, credit_note, outstanding
@@ -72,6 +71,9 @@ class ReceivablePayableReport(object):
# fetch future payments against invoices
self.get_future_payments()
# Get return entries
self.get_return_entries()
self.data = []
for gle in self.gl_entries:
self.update_voucher_balance(gle)
@@ -90,6 +92,7 @@ class ReceivablePayableReport(object):
party = gle.party,
posting_date = gle.posting_date,
remarks = gle.remarks,
account_currency = gle.account_currency,
invoiced = 0.0,
paid = 0.0,
credit_note = 0.0,
@@ -105,7 +108,6 @@ class ReceivablePayableReport(object):
# get the row where this balance needs to be updated
# if its a payment, it will return the linked invoice or will be considered as advance
row = self.get_voucher_balance(gle)
# gle_balance will be the total "debit - credit" for receivable type reports and
# and vice-versa for payable type reports
gle_balance = self.get_gle_balance(gle)
@@ -130,7 +132,18 @@ class ReceivablePayableReport(object):
if gle.against_voucher:
# find invoice
voucher_balance = self.voucher_balance.get((gle.against_voucher_type, gle.against_voucher, gle.party))
against_voucher = gle.against_voucher
# If payment is made against credit note
# and credit note is made against a Sales Invoice
# then consider the payment against original sales invoice.
if gle.against_voucher_type in ('Sales Invoice', 'Purchase Invoice'):
if gle.against_voucher in self.return_entries:
return_against = self.return_entries.get(gle.against_voucher)
if return_against:
against_voucher = return_against
voucher_balance = self.voucher_balance.get((gle.against_voucher_type, against_voucher, gle.party))
if not voucher_balance:
# no invoice, this is an invoice / stand-alone payment / credit note
@@ -257,7 +270,6 @@ class ReceivablePayableReport(object):
# customer / supplier name
party_details = self.get_party_details(row.party)
row.update(party_details)
if self.filters.get(scrub(self.filters.party_type)):
row.currency = row.account_currency
else:
@@ -422,6 +434,19 @@ class ReceivablePayableReport(object):
if row.future_ref:
row.future_ref = ', '.join(row.future_ref)
def get_return_entries(self):
doctype = "Sales Invoice" if self.party_type == "Customer" else "Purchase Invoice"
filters={
'is_return': 1,
'docstatus': 1
}
party_field = scrub(self.filters.party_type)
if self.filters.get(party_field):
filters.update({party_field: self.filters.get(party_field)})
self.return_entries = frappe._dict(
frappe.get_all(doctype, filters, ['name', 'return_against'], as_list=1)
)
def set_ageing(self, row):
if self.filters.ageing_based_on == "Due Date":
entry_date = row.due_date
@@ -677,11 +702,11 @@ class ReceivablePayableReport(object):
def get_chart_data(self):
rows = []
for row in self.data:
rows.append(
{
'values': [row.range1, row.range2, row.range3, row.range4, row.range5]
}
)
values = [row.range1, row.range2, row.range3, row.range4, row.range5]
precision = cint(frappe.db.get_default("float_precision")) or 2
rows.append({
'values': [flt(val, precision) for val in values]
})
self.chart = {
"data": {

View File

@@ -154,28 +154,31 @@ class GrossProfitGenerator(object):
def get_average_rate_based_on_group_by(self):
# sum buying / selling totals for group
for key in list(self.grouped):
for i, row in enumerate(self.grouped[key]):
if row.parent in self.returned_invoices \
and row.item_code in self.returned_invoices[row.parent]:
returned_item_rows = self.returned_invoices[row.parent][row.item_code]
for returned_item_row in returned_item_rows:
row.qty += returned_item_row.qty
row.base_amount += flt(returned_item_row.base_amount, self.currency_precision)
row.buying_amount = flt(row.qty * row.buying_rate, self.currency_precision)
if i==0:
new_row = row
elif self.filters.get("group_by") != "Invoice":
new_row.qty += row.qty
new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
new_row.base_amount += flt(row.base_amount, self.currency_precision)
if self.filters.get("group_by") == "Invoice" and (row.qty or row.base_amount):
self.grouped_data_based_on_group_by(row)
if self.filters.get("group_by") != "Invoice":
for i, row in enumerate(self.grouped[key]):
if i==0:
new_row = row
else:
new_row.qty += row.qty
new_row.buying_amount += flt(row.buying_amount, self.currency_precision)
new_row.base_amount += flt(row.base_amount, self.currency_precision)
new_row = self.set_average_rate(new_row)
self.grouped_data.append(new_row)
else:
for i, row in enumerate(self.grouped[key]):
if row.parent in self.returned_invoices \
and row.item_code in self.returned_invoices[row.parent]:
returned_item_rows = self.returned_invoices[row.parent][row.item_code]
for returned_item_row in returned_item_rows:
row.qty += returned_item_row.qty
row.base_amount += flt(returned_item_row.base_amount, self.currency_precision)
row.buying_amount = flt(row.qty * row.buying_rate, self.currency_precision)
if row.qty or row.base_amount:
row = self.set_average_rate(row)
self.grouped_data.append(row)
self.grouped_data_based_on_group_by(new_row)
def grouped_data_based_on_group_by(self, row):
row = self.set_average_rate(row)
self.grouped_data.append(row)
def set_average_rate(self, new_row):
new_row.gross_profit = flt(new_row.base_amount - new_row.buying_amount, self.currency_precision)
@@ -204,10 +207,7 @@ class GrossProfitGenerator(object):
.setdefault(inv.item_code, []).append(inv)
def skip_row(self, row, product_bundles):
if self.filters.get("group_by") != "Invoice":
if not row.get(scrub(self.filters.get("group_by", ""))):
return True
elif row.get("is_return") == 1:
if row.get("is_return") == 1:
return True
def get_buying_amount_from_product_bundle(self, row, product_bundle):

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

@@ -4,6 +4,7 @@
from __future__ import unicode_literals
import frappe
from frappe.utils import flt
from frappe.model.meta import get_field_precision
from frappe import msgprint, _
def execute(filters=None):
@@ -67,8 +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))
total_tax += tax_amount
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)
row.append(tax_amount)
# total tax, grand total, outstanding amount & rounded total

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

@@ -1114,8 +1114,22 @@ def update_child_qty_rate(parent_doctype, trans_items, parent_doctype_name):
else:
child_item.rate = flt(d.get("rate"))
if flt(child_item.price_list_rate):
child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0, \
child_item.precision("discount_percentage"))
if flt(child_item.rate) > flt(child_item.price_list_rate):
# if rate is greater than price_list_rate, set margin
# or set discount
child_item.discount_percentage = 0
child_item.margin_type = "Amount"
child_item.margin_rate_or_amount = flt(child_item.rate - child_item.price_list_rate,
child_item.precision("margin_rate_or_amount"))
child_item.rate_with_margin = child_item.rate
else:
child_item.discount_percentage = flt((1 - flt(child_item.rate) / flt(child_item.price_list_rate)) * 100.0,
child_item.precision("discount_percentage"))
child_item.discount_amount = flt(
child_item.price_list_rate) - flt(child_item.rate)
child_item.margin_type = ""
child_item.margin_rate_or_amount = 0
child_item.rate_with_margin = 0
child_item.flags.ignore_validate_update_after_submit = True
child_item.save()

View File

@@ -515,10 +515,15 @@ class BuyingController(StockController):
for d in self.get('supplied_items'):
# negative quantity is passed, as raw material qty has to be decreased
# when PR is submitted and it has to be increased when PR is cancelled
incoming_rate = 0
if self.is_return and self.return_against and self.docstatus==1:
incoming_rate = self.get_incoming_rate_for_sales_return(d.rm_item_code, self.return_against)
sl_entries.append(self.get_sl_entries(d, {
"item_code": d.rm_item_code,
"warehouse": self.supplier_warehouse,
"actual_qty": -1*flt(d.consumed_qty),
"incoming_rate": incoming_rate
}))
def on_submit(self):

View File

@@ -292,6 +292,7 @@ def copy_attributes_to_variant(item, variant):
if not variant.description:
variant.description = ""
else:
if item.variant_based_on=='Item Attribute':
if variant.attributes:
attributes_description = item.description + " "
@@ -299,7 +300,7 @@ def copy_attributes_to_variant(item, variant):
attributes_description += "<div>" + d.attribute + ": " + cstr(d.attribute_value) + "</div>"
if attributes_description not in variant.description:
variant.description += attributes_description
variant.description = attributes_description
def make_variant_item_code(template_item_code, template_item_name, variant):
"""Uses template's item code and abbreviations to make variant's item code"""

View File

@@ -306,8 +306,9 @@ class SellingController(StockController):
if flt(d.conversion_factor)==0.0:
d.conversion_factor = get_conversion_factor(d.item_code, d.uom).get("conversion_factor") or 1.0
return_rate = 0
if cint(self.is_return) and self.return_against and self.docstatus==1:
return_rate = self.get_incoming_rate_for_sales_return(d.item_code, self.return_against)
if cint(self.is_return) and self.docstatus==1:
return_rate = self.get_incoming_rate_for_sales_return(d.item_code,
d.warehouse, self.return_against)
# On cancellation or if return entry submission, make stock ledger entry for
# target warehouse first, to update serial no values properly

View File

@@ -299,7 +299,7 @@ class StockController(AccountsController):
return serialized_items
def get_incoming_rate_for_sales_return(self, item_code, against_document):
def get_incoming_rate_for_sales_return(self, item_code, warehouse, against_document):
incoming_rate = 0.0
if against_document and item_code:
incoming_rate = frappe.db.sql("""select abs(stock_value_difference / actual_qty)
@@ -308,6 +308,9 @@ class StockController(AccountsController):
and item_code = %s limit 1""",
(self.doctype, against_document, item_code))
incoming_rate = incoming_rate[0][0] if incoming_rate else 0.0
else:
incoming_rate = get_valuation_rate(item_code, warehouse,
self.doctype, against_document, company=self.company, currency=self.currency)
return incoming_rate

File diff suppressed because it is too large Load Diff

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

@@ -67,7 +67,7 @@ def get_communication_details(filters):
communication_count = None
communication_list = []
opportunities = frappe.db.get_values('Opportunity', {'opportunity_from': 'Lead'},\
['name', 'customer_name', 'lead', 'contact_email'], as_dict=1)
['name', 'customer_name', 'contact_email'], as_dict=1)
for d in opportunities:
invoice = frappe.db.sql('''

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",

File diff suppressed because it is too large Load Diff

View File

@@ -13,6 +13,7 @@ class Loan(AccountsController):
def validate(self):
validate_repayment_method(self.repayment_method, self.loan_amount, self.monthly_repayment_amount, self.repayment_periods)
self.set_missing_fields()
self.validate_loan_application()
self.make_repayment_schedule()
self.set_repayment_period()
self.calculate_totals()
@@ -33,6 +34,13 @@ class Loan(AccountsController):
if self.status == "Repaid/Closed":
self.total_amount_paid = self.total_payment
def validate_loan_application(self):
if self.loan_application:
loan = frappe.db.get_value("Loan", {"loan_application": self.loan_application}, "name")
if loan and loan != self.name:
frappe.throw(_("Loan {0} already created for Loan Application {1}").format(frappe.bold(loan),
frappe.bold(self.loan_application)))
def make_jv_entry(self):
self.check_permission('write')
@@ -116,6 +124,7 @@ def update_disbursement_status(doc):
""", (doc.payment_account, doc.name), as_dict=1)[0]
disbursement_date = None
status = ''
if not disbursement or disbursement.disbursed_amount == 0:
status = "Sanctioned"
elif disbursement.disbursed_amount == doc.loan_amount:

View File

@@ -23,20 +23,25 @@ frappe.ui.form.on('Loan Application', {
},
add_toolbar_buttons: function(frm) {
if (frm.doc.status == "Approved") {
frm.add_custom_button(__('Create Loan'), function() {
frappe.call({
method: "erpnext.hr.doctype.loan_application.loan_application.make_loan",
args: {
"source_name": frm.doc.name
},
callback: function(r) {
if(!r.exc) {
var doc = frappe.model.sync(r.message);
frappe.set_route("Form", r.message.doctype, r.message.name);
}
}
});
}).addClass("btn-primary");
// show create loan button if loan not created against loan aplication
frappe.db.get_value("Loan", {"loan_application": frm.doc.name}, "name", (r) => {
if (!r) {
frm.add_custom_button(__('Create Loan'), function() {
frappe.call({
method: "erpnext.hr.doctype.loan_application.loan_application.make_loan",
args: {
"source_name": frm.doc.name
},
callback: function(r) {
if(!r.exc) {
var doc = frappe.model.sync(r.message);
frappe.set_route("Form", r.message.doctype, r.message.name);
}
}
});
}).addClass("btn-primary");
}
});
}
}
});

View File

@@ -117,7 +117,7 @@ frappe.ui.form.on("BOM", {
args: {
update_parent: true,
from_child_bom:false,
save: false
save: frm.doc.docstatus === 1 ? true : false
},
callback: function(r) {
refresh_field("items");

View File

@@ -34,7 +34,8 @@ class BOM(WebsiteGenerator):
# name can be BOM/ITEM/001, BOM/ITEM/001-1, BOM-ITEM-001, BOM-ITEM-001-1
# split by item
names = [name.split(self.item)[-1][1:] for name in names]
names = [name.split(self.item, 1) for name in names]
names = [d[-1][1:] for d in filter(lambda x: len(x) > 1 and x[-1], names)]
# split by (-) if cancelled
names = [cint(name.split('-')[-1]) for name in names]

View File

@@ -204,6 +204,8 @@ class WorkOrder(Document):
self.meta.get_label(fieldname), qty, completed_qty, self.name), StockOverProductionError)
self.db_set(fieldname, qty)
from erpnext.selling.doctype.sales_order.sales_order import update_produced_qty_in_so_item
update_produced_qty_in_so_item(self.sales_order_item)
if self.production_plan:
self.update_production_plan_status()

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

@@ -606,3 +606,4 @@ erpnext.patches.v11_1.set_missing_opportunity_from
erpnext.patches.v11_1.set_quotation_status
erpnext.patches.v11_1.update_default_supplier_in_item_defaults
erpnext.patches.v11_1.set_status_for_material_request_type_manufacture
erpnext.patches.v11_1.set_produced_qty_field_in_sales_order_for_work_order

View File

@@ -0,0 +1,9 @@
import frappe
from erpnext.selling.doctype.sales_order.sales_order import update_produced_qty_in_so_item
def execute():
frappe.reload_doctype('Sales Order Item')
frappe.reload_doctype('Sales Order')
sales_order_items = frappe.db.get_all('Sales Order Item', ['name'])
for so_item in sales_order_items:
update_produced_qty_in_so_item(so_item.get('name'))

View File

@@ -200,7 +200,11 @@ class Project(Document):
frappe.db.set_value("Sales Order", self.sales_order, "project", self.name)
def update_percent_complete(self, from_validate=False):
if not self.tasks: return
if not self.tasks:
if self.status == "Completed" :
self.percent_complete = 100
return
total = frappe.db.sql("""select count(name) from tabTask where project=%s""", self.name)[0][0]
if not total and self.percent_complete:
self.percent_complete = 0

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

@@ -19,7 +19,7 @@
{%- endmacro %}
{%- macro render_discount_or_margin(item) -%}
{%- if item.discount_percentage > 0.0 or item.margin_type %}
{%- if (item.discount_percentage and item.discount_percentage > 0.0) or item.margin_type %}
<ScontoMaggiorazione>
{%- if item.discount_percentage > 0.0 %}
<Tipo>SC</Tipo>

View File

@@ -153,8 +153,7 @@ def get_invoice_summary(items, taxes):
tax_rate=tax.rate,
tax_amount=(reference_row.tax_amount * tax.rate) / 100,
net_amount=reference_row.tax_amount,
taxable_amount=(reference_row.tax_amount if tax.charge_type == 'On Previous Row Amount'
else reference_row.total),
taxable_amount=reference_row.tax_amount,
item_tax_rate={tax.account_head: tax.rate},
charges=True,
type="Actual",
@@ -189,6 +188,10 @@ def get_invoice_summary(items, taxes):
summary_data[key]["tax_exemption_reason"] = tax.tax_exemption_reason
summary_data[key]["tax_exemption_law"] = tax.tax_exemption_law
if summary_data.get("0.0") and tax.charge_type in ["On Previous Row Total",
"On Previous Row Amount"]:
summary_data[key]["taxable_amount"] = tax.total
if summary_data == {}: #Implies that Zero VAT has not been set on any item.
summary_data.setdefault("0.0", {"tax_amount": 0.0, "taxable_amount": tax.total,
"tax_exemption_reason": tax.tax_exemption_reason, "tax_exemption_law": tax.tax_exemption_law})

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

@@ -340,6 +340,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

@@ -973,3 +973,15 @@ def make_raw_material_request(items, company, sales_order, project=None):
material_request.run_method("set_missing_values")
material_request.submit()
return material_request
def update_produced_qty_in_so_item(sales_order_item):
#for multiple work orders against same sales order item
linked_wo_with_so_item = frappe.db.get_all('Work Order', ['produced_qty'], {
'sales_order_item': sales_order_item,
'docstatus': 1
})
if len(linked_wo_with_so_item) > 0:
total_produced_qty = 0
for wo in linked_wo_with_so_item:
total_produced_qty += flt(wo.get('produced_qty'))
frappe.db.set_value('Sales Order Item', sales_order_item, 'produced_qty', total_produced_qty)

View File

@@ -21,6 +21,7 @@
"bold": 1,
"collapsible": 0,
"columns": 3,
"fetch_if_empty": 0,
"fieldname": "item_code",
"fieldtype": "Link",
"hidden": 0,
@@ -57,6 +58,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "customer_item_code",
"fieldtype": "Data",
"hidden": 1,
@@ -88,6 +90,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "ensure_delivery_based_on_produced_serial_no",
"fieldtype": "Check",
"hidden": 0,
@@ -120,6 +123,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break1",
"fieldtype": "Column Break",
"hidden": 0,
@@ -150,6 +154,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_name",
"fieldtype": "Data",
"hidden": 0,
@@ -185,6 +190,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_5",
"fieldtype": "Section Break",
"hidden": 0,
@@ -217,6 +223,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "description",
"fieldtype": "Text Editor",
"hidden": 0,
@@ -252,6 +259,7 @@
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "delivery_date",
"fieldtype": "Date",
"hidden": 0,
@@ -284,6 +292,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_7",
"fieldtype": "Column Break",
"hidden": 0,
@@ -315,6 +324,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "image",
"fieldtype": "Attach",
"hidden": 1,
@@ -347,6 +357,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "image_view",
"fieldtype": "Image",
"hidden": 0,
@@ -380,6 +391,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "quantity_and_rate",
"fieldtype": "Section Break",
"hidden": 0,
@@ -411,6 +423,7 @@
"bold": 0,
"collapsible": 0,
"columns": 1,
"fetch_if_empty": 0,
"fieldname": "qty",
"fieldtype": "Float",
"hidden": 0,
@@ -446,6 +459,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "stock_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -482,6 +496,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break2",
"fieldtype": "Column Break",
"hidden": 0,
@@ -512,6 +527,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "uom",
"fieldtype": "Link",
"hidden": 0,
@@ -545,6 +561,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "conversion_factor",
"fieldtype": "Float",
"hidden": 0,
@@ -577,6 +594,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "stock_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -609,6 +627,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_16",
"fieldtype": "Section Break",
"hidden": 0,
@@ -640,6 +659,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "price_list_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -676,6 +696,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_price_list_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -712,6 +733,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "discount_and_margin",
"fieldtype": "Section Break",
"hidden": 0,
@@ -745,6 +767,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "price_list_rate",
"fetch_if_empty": 0,
"fieldname": "margin_type",
"fieldtype": "Select",
"hidden": 0,
@@ -779,6 +802,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.margin_type && doc.price_list_rate",
"fetch_if_empty": 0,
"fieldname": "margin_rate_or_amount",
"fieldtype": "Float",
"hidden": 0,
@@ -812,6 +836,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount",
"fetch_if_empty": 0,
"fieldname": "rate_with_margin",
"fieldtype": "Currency",
"hidden": 0,
@@ -845,6 +870,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_19",
"fieldtype": "Column Break",
"hidden": 0,
@@ -877,6 +903,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "price_list_rate",
"fetch_if_empty": 0,
"fieldname": "discount_percentage",
"fieldtype": "Percent",
"hidden": 0,
@@ -913,6 +940,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "discount_percentage",
"fetch_if_empty": 0,
"fieldname": "discount_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -947,6 +975,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.margin_type && doc.price_list_rate && doc.margin_rate_or_amount",
"fetch_if_empty": 0,
"fieldname": "base_rate_with_margin",
"fieldtype": "Currency",
"hidden": 0,
@@ -980,6 +1009,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_simple1",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1012,6 +1042,7 @@
"collapsible": 0,
"columns": 2,
"depends_on": "eval: doc.type != \"\"",
"fetch_if_empty": 0,
"fieldname": "rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1048,6 +1079,7 @@
"bold": 0,
"collapsible": 0,
"columns": 2,
"fetch_if_empty": 0,
"fieldname": "amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1085,6 +1117,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break3",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1115,6 +1148,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1151,6 +1185,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1187,6 +1222,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "pricing_rule",
"fieldtype": "Link",
"hidden": 0,
@@ -1219,6 +1255,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_24",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1250,6 +1287,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "net_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1283,6 +1321,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "net_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1316,6 +1355,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_27",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1347,6 +1387,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_net_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1380,6 +1421,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "base_net_amount",
"fieldtype": "Currency",
"hidden": 0,
@@ -1414,6 +1456,7 @@
"collapsible": 1,
"collapsible_depends_on": "eval:doc.delivered_by_supplier==1||doc.supplier",
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "drop_ship_section",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1446,6 +1489,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "delivered_by_supplier",
"fieldtype": "Check",
"hidden": 0,
@@ -1478,6 +1522,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "supplier",
"fieldtype": "Link",
"hidden": 0,
@@ -1511,6 +1556,7 @@
"bold": 0,
"collapsible": 1,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_weight_details",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1543,6 +1589,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "weight_per_unit",
"fieldtype": "Float",
"hidden": 0,
@@ -1575,6 +1622,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "total_weight",
"fieldtype": "Float",
"hidden": 0,
@@ -1607,6 +1655,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "column_break_21",
"fieldtype": "Column Break",
"hidden": 0,
@@ -1638,6 +1687,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "weight_uom",
"fieldtype": "Link",
"hidden": 0,
@@ -1671,6 +1721,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "warehouse_and_reference",
"fieldtype": "Section Break",
"hidden": 0,
@@ -1703,6 +1754,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.delivered_by_supplier!=1",
"fetch_if_empty": 0,
"fieldname": "warehouse",
"fieldtype": "Link",
"hidden": 0,
@@ -1740,6 +1792,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "eval:doc.delivered_by_supplier!=1",
"fetch_if_empty": 0,
"fieldname": "target_warehouse",
"fieldtype": "Link",
"hidden": 1,
@@ -1773,6 +1826,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "prevdoc_docname",
"fieldtype": "Link",
"hidden": 0,
@@ -1807,6 +1861,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "brand",
"fieldtype": "Link",
"hidden": 1,
@@ -1842,6 +1897,7 @@
"collapsible": 0,
"columns": 0,
"description": "",
"fetch_if_empty": 0,
"fieldname": "item_group",
"fieldtype": "Link",
"hidden": 1,
@@ -1876,6 +1932,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "billed_amt",
"fieldtype": "Currency",
"hidden": 0,
@@ -1908,6 +1965,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "valuation_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -1941,6 +1999,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "gross_profit",
"fieldtype": "Currency",
"hidden": 0,
@@ -1974,6 +2033,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "blanket_order",
"fieldtype": "Link",
"hidden": 0,
@@ -2007,6 +2067,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "blanket_order_rate",
"fieldtype": "Currency",
"hidden": 0,
@@ -2039,6 +2100,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "page_break",
"fieldtype": "Check",
"hidden": 0,
@@ -2072,6 +2134,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "col_break4",
"fieldtype": "Column Break",
"hidden": 0,
@@ -2102,6 +2165,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "projected_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2137,6 +2201,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "actual_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2170,6 +2235,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "ordered_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2202,6 +2268,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "delivered_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2237,6 +2304,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "work_order_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2270,6 +2338,7 @@
"collapsible": 0,
"columns": 0,
"depends_on": "returned_qty",
"fetch_if_empty": 0,
"fieldname": "returned_qty",
"fieldtype": "Float",
"hidden": 0,
@@ -2302,6 +2371,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "section_break_63",
"fieldtype": "Section Break",
"hidden": 0,
@@ -2334,6 +2404,7 @@
"collapsible": 0,
"columns": 0,
"description": "For Production",
"fetch_if_empty": 0,
"fieldname": "planned_qty",
"fieldtype": "Float",
"hidden": 1,
@@ -2370,9 +2441,10 @@
"collapsible": 0,
"columns": 0,
"description": "For Production",
"fetch_if_empty": 0,
"fieldname": "produced_qty",
"fieldtype": "Float",
"hidden": 1,
"hidden": 0,
"ignore_user_permissions": 0,
"ignore_xss_filter": 0,
"in_filter": 0,
@@ -2405,6 +2477,7 @@
"bold": 0,
"collapsible": 0,
"columns": 0,
"fetch_if_empty": 0,
"fieldname": "item_tax_rate",
"fieldtype": "Code",
"hidden": 1,
@@ -2439,6 +2512,7 @@
"collapsible": 0,
"columns": 0,
"description": "Used for Production Plan",
"fetch_if_empty": 0,
"fieldname": "transaction_date",
"fieldtype": "Date",
"hidden": 1,
@@ -2477,8 +2551,8 @@
"istable": 1,
"max_attachments": 0,
"menu_index": 0,
"modified": "2019-02-18 18:53:23.425126",
"modified_by": "Administrator",
"modified": "2019-09-30 16:58:52.524894",
"modified_by": "ruchamahabal2@gmail.com",
"module": "Selling",
"name": "Sales Order Item",
"owner": "Administrator",

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

@@ -80,10 +80,14 @@ frappe.query_reports["Sales Analytics"] = {
var tree_type = frappe.query_report.filters[0].value;
if(tree_type == "Customer" || tree_type == "Item") {
if(tree_type == "Customer") {
row_values = data.slice(4,length-1).map(function (column) {
return column.content;
})
} else if (tree_type == "Item") {
row_values = data.slice(5,length-1).map(function (column) {
return column.content;
})
}
else {
row_values = data.slice(3,length-1).map(function (column) {

View File

@@ -114,7 +114,7 @@ class Analytics(object):
if self.filters["value_quantity"] == 'Value':
value_field = 'base_amount'
else:
value_field = 'qty'
value_field = 'stock_qty'
self.entries = frappe.db.sql("""
select i.item_code as entity, i.item_name as entity_name, i.stock_uom, i.{value_field} as value_field, s.{date_field}
@@ -301,8 +301,10 @@ class Analytics(object):
def get_chart_data(self):
length = len(self.columns)
if self.filters.tree_type in ["Customer", "Supplier", "Item"]:
labels = [d.get("label") for d in self.columns[2:length-1]]
if self.filters.tree_type in ["Customer", "Supplier"]:
labels = [d.get("label") for d in self.columns[2:length - 1]]
elif self.filters.tree_type == "Item":
labels = [d.get("label") for d in self.columns[3:length - 1]]
else:
labels = [d.get("label") for d in self.columns[1:length-1]]
self.chart = {

View File

@@ -105,10 +105,10 @@ erpnext.stock.PurchaseReceiptController = erpnext.buying.BuyingController.extend
cur_frm.add_custom_button(__("Close"), this.close_purchase_receipt, __("Status"))
}
cur_frm.add_custom_button(__('Return'), this.make_purchase_return, __("Make"));
cur_frm.add_custom_button(__('Purchase Return'), this.make_purchase_return, __("Make"));
if(flt(this.frm.doc.per_billed) < 100) {
cur_frm.add_custom_button(__('Invoice'), this.make_purchase_invoice, __("Make"));
cur_frm.add_custom_button(__('Purchase Invoice'), this.make_purchase_invoice, __("Make"));
}
cur_frm.add_custom_button(__('Retention Stock Entry'), this.make_retention_stock_entry, __("Make"));

View File

@@ -24,7 +24,7 @@ def execute(filters=None):
data = []
for item in items:
total_outgoing = consumed_item_map.get(item.name, 0) + delivered_item_map.get(item.name,0)
total_outgoing = flt(consumed_item_map.get(item.name, 0)) + flt(delivered_item_map.get(item.name,0))
avg_daily_outgoing = flt(total_outgoing / diff, float_preceision)
reorder_level = (avg_daily_outgoing * flt(item.lead_time_days)) + flt(item.safety_stock)
@@ -55,18 +55,20 @@ def get_item_info(filters):
def get_consumed_items(condition):
cn_items = frappe.db.sql("""select se_item.item_code,
sum(se_item.transfer_qty) as 'consume_qty'
from `tabStock Entry` se, `tabStock Entry Detail` se_item
where se.name = se_item.parent and se.docstatus = 1
and (ifnull(se_item.t_warehouse, '') = '' or se.purpose = 'Subcontract') %s
group by se_item.item_code""" % (condition), as_dict=1)
consumed_items = frappe.db.sql("""
select item_code, abs(sum(actual_qty)) as consumed_qty
from `tabStock Ledger Entry`
where actual_qty < 0
and voucher_type not in ('Delivery Note', 'Sales Invoice')
%s
group by item_code
""" % condition, as_dict=1)
cn_items_map = {}
for item in cn_items:
cn_items_map.setdefault(item.item_code, item.consume_qty)
consumed_items_map = {}
for item in consumed_items:
consumed_items_map.setdefault(item.item_code, item.consumed_qty)
return cn_items_map
return consumed_items_map
def get_delivered_items(condition):
dn_items = frappe.db.sql("""select dn_item.item_code, sum(dn_item.stock_qty) as dn_qty

View File

@@ -3,10 +3,10 @@
from __future__ import print_function, unicode_literals
import frappe
from frappe.utils import flt, cstr, nowdate, nowtime
from erpnext.stock.utils import update_bin
from erpnext.stock.stock_ledger import update_entries_after
from erpnext.controllers.stock_controller import update_gl_entries_after
def repost(only_actual=False, allow_negative_stock=False, allow_zero_rate=False, only_bin=False):
"""
@@ -18,23 +18,29 @@ def repost(only_actual=False, allow_negative_stock=False, allow_zero_rate=False,
existing_allow_negative_stock = frappe.db.get_value("Stock Settings", None, "allow_negative_stock")
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", 1)
for d in frappe.db.sql("""select distinct item_code, warehouse from
(select item_code, warehouse from tabBin
union
select item_code, warehouse from `tabStock Ledger Entry`) a"""):
try:
repost_stock(d[0], d[1], allow_zero_rate, only_actual, only_bin)
frappe.db.commit()
except:
frappe.db.rollback()
item_warehouses = frappe.db.sql("""
select distinct item_code, warehouse
from
(select item_code, warehouse from tabBin
union
select item_code, warehouse from `tabStock Ledger Entry`) a
""")
for d in item_warehouses:
try:
repost_stock(d[0], d[1], allow_zero_rate, only_actual, only_bin, allow_negative_stock)
frappe.db.commit()
except:
frappe.db.rollback()
if allow_negative_stock:
frappe.db.set_value("Stock Settings", None, "allow_negative_stock", existing_allow_negative_stock)
frappe.db.auto_commit_on_many_writes = 0
def repost_stock(item_code, warehouse, allow_zero_rate=False, only_actual=False, only_bin=False):
def repost_stock(item_code, warehouse, allow_zero_rate=False,
only_actual=False, only_bin=False, allow_negative_stock=False):
if not only_bin:
repost_actual_qty(item_code, warehouse, allow_zero_rate)
repost_actual_qty(item_code, warehouse, allow_zero_rate, allow_negative_stock)
if item_code and warehouse and not only_actual:
qty_dict = {
@@ -50,11 +56,8 @@ def repost_stock(item_code, warehouse, allow_zero_rate=False, only_actual=False,
update_bin_qty(item_code, warehouse, qty_dict)
def repost_actual_qty(item_code, warehouse, allow_zero_rate=False):
try:
update_entries_after({ "item_code": item_code, "warehouse": warehouse }, allow_zero_rate)
except:
pass
def repost_actual_qty(item_code, warehouse, allow_zero_rate=False, allow_negative_stock=False): update_entries_after({ "item_code": item_code, "warehouse": warehouse },
allow_zero_rate=allow_zero_rate, allow_negative_stock=allow_negative_stock)
def get_balance_qty_from_sle(item_code, warehouse):
balance_qty = frappe.db.sql("""select qty_after_transaction from `tabStock Ledger Entry`
@@ -227,39 +230,14 @@ def reset_serial_no_status_and_warehouse(serial_nos=None):
except:
pass
def repost_all_stock_vouchers():
warehouses_with_account = frappe.db.sql_list("""select warehouse from tabAccount
where ifnull(account_type, '') = 'Stock' and (warehouse is not null and warehouse != '')
and is_group=0""")
def repost_gle_for_stock_transactions(posting_date=None, posting_time=None, for_warehouses=None):
frappe.db.auto_commit_on_many_writes = 1
vouchers = frappe.db.sql("""select distinct voucher_type, voucher_no
from `tabStock Ledger Entry` sle
where voucher_type != "Serial No" and sle.warehouse in (%s)
order by posting_date, posting_time, name""" %
', '.join(['%s']*len(warehouses_with_account)), tuple(warehouses_with_account))
if not posting_date:
posting_date = "1900-01-01"
if not posting_time:
posting_time = "00:00"
rejected = []
i = 0
for voucher_type, voucher_no in vouchers:
i+=1
print(i, "/", len(vouchers), voucher_type, voucher_no)
try:
for dt in ["Stock Ledger Entry", "GL Entry"]:
frappe.db.sql("""delete from `tab%s` where voucher_type=%s and voucher_no=%s"""%
(dt, '%s', '%s'), (voucher_type, voucher_no))
update_gl_entries_after(posting_date, posting_time, for_warehouses=for_warehouses)
doc = frappe.get_doc(voucher_type, voucher_no)
if voucher_type=="Stock Entry" and doc.purpose in ["Manufacture", "Repack"]:
doc.calculate_rate_and_amount(force=1)
elif voucher_type=="Purchase Receipt" and doc.is_subcontracted == "Yes":
doc.validate()
doc.update_stock_ledger()
doc.make_gl_entries(repost_future_gle=False)
frappe.db.commit()
except Exception:
print(frappe.get_traceback())
rejected.append([voucher_type, voucher_no])
frappe.db.rollback()
print(rejected)
frappe.db.auto_commit_on_many_writes = 0