mirror of
https://github.com/frappe/erpnext.git
synced 2026-08-02 01:04:36 +00:00
Compare commits
72 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47420578ae | ||
|
|
35d8cd9f10 | ||
|
|
1e55ac6a4f | ||
|
|
ff7a5d18d1 | ||
|
|
5a15dcc060 | ||
|
|
cec6c87e09 | ||
|
|
b2870b9426 | ||
|
|
e27600066c | ||
|
|
5b8c624b34 | ||
|
|
9e8531d68e | ||
|
|
ebeb137351 | ||
|
|
8c7d28a41a | ||
|
|
d90b80af86 | ||
|
|
b62e17f7f2 | ||
|
|
5169dc1566 | ||
|
|
d3afecd1d9 | ||
|
|
ec56984e12 | ||
|
|
1c26623f22 | ||
|
|
02cb668f22 | ||
|
|
bd749dce18 | ||
|
|
737a504a35 | ||
|
|
c719f842bc | ||
|
|
0d19139acf | ||
|
|
80973bb8de | ||
|
|
a9a7e84873 | ||
|
|
78776c42fe | ||
|
|
2d9908d22f | ||
|
|
3b0695e0ca | ||
|
|
a9695f04de | ||
|
|
a2398775cd | ||
|
|
f2544ec7f2 | ||
|
|
778d7b9cbd | ||
|
|
2a3c62e7f6 | ||
|
|
5c576e4365 | ||
|
|
c57753a234 | ||
|
|
7cabcdd9a2 | ||
|
|
2b0c845cb8 | ||
|
|
71e51714f2 | ||
|
|
62767ced3e | ||
|
|
cf71643685 | ||
|
|
d225f5993b | ||
|
|
3dc8941be7 | ||
|
|
dbebec8fcc | ||
|
|
4111965d2e | ||
|
|
3ac54a0ba6 | ||
|
|
143f007272 | ||
|
|
3fc10a8da1 | ||
|
|
ed1e28b8fa | ||
|
|
71145c699f | ||
|
|
ea6d90988f | ||
|
|
6efe4acb1d | ||
|
|
ad2365502f | ||
|
|
9c428ebfba | ||
|
|
b53e4404dc | ||
|
|
0bc849975c | ||
|
|
690139ca11 | ||
|
|
c0a21ad96a | ||
|
|
8c9fd62775 | ||
|
|
0be054ae0f | ||
|
|
912cf9d555 | ||
|
|
7fe0a2023a | ||
|
|
cf191c0483 | ||
|
|
bb8d9f2a57 | ||
|
|
fa4577d18a | ||
|
|
993521d365 | ||
|
|
3372b7411d | ||
|
|
5dbfeb8557 | ||
|
|
f5d2337176 | ||
|
|
67aa7b8735 | ||
|
|
aea67c9843 | ||
|
|
f64aaf5e1c | ||
|
|
00f6fd827e |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -13,4 +13,5 @@ erpnext/docs/current
|
||||
__pycache__
|
||||
*~
|
||||
.vscode/
|
||||
node_modules/
|
||||
node_modules/
|
||||
.idea/
|
||||
@@ -5,7 +5,7 @@ import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
from frappe.utils import getdate
|
||||
|
||||
__version__ = '11.1.59'
|
||||
__version__ = '11.1.65'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
|
||||
@@ -167,7 +167,7 @@ erpnext.accounts.JournalEntry = frappe.ui.form.Controller.extend({
|
||||
filters: {
|
||||
'account': row.account
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
me.frm.set_query("reference_name", "accounts", function(doc, cdt, cdn) {
|
||||
|
||||
@@ -41,6 +41,8 @@ def get_pos_data():
|
||||
items_list = get_items_list(pos_profile, doc.company)
|
||||
customers = get_customers_list(pos_profile)
|
||||
|
||||
doc.plc_conversion_rate = update_plc_conversion_rate(doc, pos_profile)
|
||||
|
||||
return {
|
||||
'doc': doc,
|
||||
'default_customer': pos_profile.get('customer'),
|
||||
@@ -53,7 +55,7 @@ def get_pos_data():
|
||||
'batch_no_data': get_batch_no_data(),
|
||||
'barcode_data': get_barcode_data(items_list),
|
||||
'tax_data': get_item_tax_data(),
|
||||
'price_list_data': get_price_list_data(doc.selling_price_list),
|
||||
'price_list_data': get_price_list_data(doc.selling_price_list, doc.plc_conversion_rate),
|
||||
'customer_wise_price_list': get_customer_wise_price_list(),
|
||||
'bin_data': get_bin_data(pos_profile),
|
||||
'pricing_rules': get_pricing_rule_data(doc),
|
||||
@@ -62,6 +64,15 @@ def get_pos_data():
|
||||
'meta': get_meta()
|
||||
}
|
||||
|
||||
def update_plc_conversion_rate(doc, pos_profile):
|
||||
conversion_rate = 1.0
|
||||
|
||||
price_list_currency = frappe.get_cached_value("Price List", doc.selling_price_list, "currency")
|
||||
if pos_profile.get("currency") != price_list_currency:
|
||||
conversion_rate = get_exchange_rate(price_list_currency,
|
||||
pos_profile.get("currency"), nowdate(), args="for_selling") or 1.0
|
||||
|
||||
return conversion_rate
|
||||
|
||||
def get_meta():
|
||||
doctype_meta = {
|
||||
@@ -317,14 +328,14 @@ def get_item_tax_data():
|
||||
return itemwise_tax
|
||||
|
||||
|
||||
def get_price_list_data(selling_price_list):
|
||||
def get_price_list_data(selling_price_list, conversion_rate):
|
||||
itemwise_price_list = {}
|
||||
price_lists = frappe.db.sql("""Select ifnull(price_list_rate, 0) as price_list_rate,
|
||||
item_code from `tabItem Price` ip where price_list = %(price_list)s""",
|
||||
{'price_list': selling_price_list}, as_dict=1)
|
||||
|
||||
for item in price_lists:
|
||||
itemwise_price_list[item.item_code] = item.price_list_rate
|
||||
itemwise_price_list[item.item_code] = item.price_list_rate * conversion_rate
|
||||
|
||||
return itemwise_price_list
|
||||
|
||||
|
||||
@@ -141,7 +141,7 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
cur_frm.meta._default_print_format = cur_frm.meta.default_print_format;
|
||||
cur_frm.meta.default_print_format = cur_frm.pos_print_format;
|
||||
}
|
||||
} else if(cur_frm.doc.is_return) {
|
||||
} else if(cur_frm.doc.is_return && !cur_frm.meta.default_print_format) {
|
||||
if(cur_frm.return_print_format) {
|
||||
cur_frm.meta._default_print_format = cur_frm.meta.default_print_format;
|
||||
cur_frm.meta.default_print_format = cur_frm.return_print_format;
|
||||
|
||||
@@ -207,7 +207,7 @@ class SalesInvoice(SellingController):
|
||||
for payment in self.payments:
|
||||
total_amount_in_payments += payment.amount
|
||||
invoice_total = self.rounded_total or self.grand_total
|
||||
if total_amount_in_payments < invoice_total:
|
||||
if flt(total_amount_in_payments, self.precision("grand_total")) < invoice_total:
|
||||
frappe.throw(_("Total payments amount can't be greater than {}".format(-invoice_total)))
|
||||
|
||||
def validate_pos_paid_amount(self):
|
||||
|
||||
@@ -1625,7 +1625,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
setTimeout(function () {
|
||||
w.print();
|
||||
w.close();
|
||||
}, 1000)
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
submit_invoice: function () {
|
||||
@@ -1682,6 +1682,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
$(this.wrapper).find('.pos-bill').css('pointer-events', pointer_events);
|
||||
$(this.wrapper).find('.pos-items-section').css('pointer-events', pointer_events);
|
||||
this.set_primary_action();
|
||||
|
||||
$(this.wrapper).find('#pos-item-disc').prop('disabled',
|
||||
this.pos_profile_data.allow_user_to_edit_discount ? false : true);
|
||||
|
||||
$(this.wrapper).find('#pos-item-price').prop('disabled',
|
||||
this.pos_profile_data.allow_user_to_edit_rate ? false : true);
|
||||
},
|
||||
|
||||
create_invoice: function () {
|
||||
@@ -1699,13 +1705,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
if (this.frm.doc.offline_pos_name
|
||||
&& in_list(existing_pos_list, this.frm.doc.offline_pos_name)) {
|
||||
this.update_invoice()
|
||||
//to retrieve and set the default payment
|
||||
invoice_data[this.frm.doc.offline_pos_name] = this.frm.doc;
|
||||
invoice_data[this.frm.doc.offline_pos_name].payments[0].amount = this.frm.doc.net_total
|
||||
invoice_data[this.frm.doc.offline_pos_name].payments[0].base_amount = this.frm.doc.net_total
|
||||
|
||||
this.frm.doc.paid_amount = this.frm.doc.net_total
|
||||
this.frm.doc.outstanding_amount = 0
|
||||
} else if(!this.frm.doc.offline_pos_name) {
|
||||
this.frm.doc.offline_pos_name = frappe.datetime.now_datetime();
|
||||
this.frm.doc.posting_date = frappe.datetime.get_today();
|
||||
@@ -1907,7 +1906,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
serial_no = me.item_serial_no[key][0];
|
||||
}
|
||||
|
||||
if (this.items[0].has_serial_no && serial_no == "") {
|
||||
if (this.items && this.items[0].has_serial_no && serial_no == "") {
|
||||
this.refresh();
|
||||
frappe.throw(__(repl("Error: Serial no is mandatory for item %(item)s", {
|
||||
'item': this.items[0].item_code
|
||||
|
||||
@@ -155,7 +155,7 @@ def set_price_list(out, party, party_type, given_price_list, pos=None):
|
||||
# price list
|
||||
price_list = get_permitted_documents('Price List')
|
||||
|
||||
if price_list:
|
||||
if price_list and len(price_list) == 1:
|
||||
price_list = price_list[0]
|
||||
elif pos and party_type == 'Customer':
|
||||
customer_price_list = frappe.get_value('Customer', party.name, 'default_price_list')
|
||||
@@ -588,4 +588,4 @@ def get_partywise_advanced_payment_amount(party_type, posting_date = None):
|
||||
.format(("credit") if party_type == "Customer" else "debit", cond) , party_type)
|
||||
|
||||
if data:
|
||||
return frappe._dict(data)
|
||||
return frappe._dict(data)
|
||||
|
||||
@@ -1,275 +1,269 @@
|
||||
<style>
|
||||
.print-format {
|
||||
padding: 4mm;
|
||||
font-size: 8.0pt !important;
|
||||
}
|
||||
.print-format td {
|
||||
vertical-align:middle !important;
|
||||
}
|
||||
</style>
|
||||
.print-format {
|
||||
padding: 4mm;
|
||||
font-size: 8.0pt !important;
|
||||
}
|
||||
.print-format td {
|
||||
vertical-align:middle !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
<h2 class="text-center" style="margin-top:0">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">
|
||||
{% if (filters.customer_name) { %}
|
||||
{%= filters.customer_name %}
|
||||
{% } else { %}
|
||||
{%= filters.customer || filters.supplier %}
|
||||
{% } %}
|
||||
</h4>
|
||||
<h6 class="text-center">
|
||||
{% if (filters.tax_id) { %}
|
||||
{%= __("Tax Id: ")%} {%= filters.tax_id %}
|
||||
<h2 class="text-center" style="margin-top:0">{%= __(report.report_name) %}</h2>
|
||||
<h4 class="text-center">
|
||||
{% if (filters.customer_name) { %}
|
||||
{%= filters.customer_name %}
|
||||
{% } else { %}
|
||||
{%= filters.customer || filters.supplier %}
|
||||
{% } %}
|
||||
</h6>
|
||||
<h5 class="text-center">
|
||||
{%= __(filters.ageing_based_on) %}
|
||||
{%= __("Until") %}
|
||||
{%= frappe.datetime.str_to_user(filters.report_date) %}
|
||||
</h5>
|
||||
</h4>
|
||||
<h6 class="text-center">
|
||||
{% if (filters.tax_id) { %}
|
||||
{%= __("Tax Id: ")%} {%= filters.tax_id %}
|
||||
{% } %}
|
||||
</h6>
|
||||
<h5 class="text-center">
|
||||
{%= __(filters.ageing_based_on) %}
|
||||
{%= __("Until") %}
|
||||
{%= frappe.datetime.str_to_user(filters.report_date) %}
|
||||
</h5>
|
||||
|
||||
<div class="clearfix">
|
||||
<div class="pull-left">
|
||||
{% if(filters.payment_terms) { %}
|
||||
<strong>{%= __("Payment Terms") %}:</strong> {%= filters.payment_terms %}
|
||||
{% } %}
|
||||
<div class="clearfix">
|
||||
<div class="pull-left">
|
||||
{% if(filters.payment_terms) { %}
|
||||
<strong>{%= __("Payment Terms") %}:</strong> {%= filters.payment_terms %}
|
||||
{% } %}
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
{% if(filters.credit_limit) { %}
|
||||
<strong>{%= __("Credit Limit") %}:</strong> {%= format_currency(filters.credit_limit) %}
|
||||
{% } %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="pull-right">
|
||||
{% if(filters.credit_limit) { %}
|
||||
<strong>{%= __("Credit Limit") %}:</strong> {%= format_currency(filters.credit_limit) %}
|
||||
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% var balance_row = data.slice(-1).pop();
|
||||
var range1 = report.columns[11].label;
|
||||
var range2 = report.columns[12].label;
|
||||
var range3 = report.columns[13].label;
|
||||
var range4 = report.columns[14].label;
|
||||
var range5 = report.columns[15].label;
|
||||
%}
|
||||
{% if(balance_row) { %}
|
||||
<table class="table table-bordered table-condensed">
|
||||
<caption class="text-right">(Amount in {%= data[0]["currency"] || "" %})</caption>
|
||||
<colgroup>
|
||||
<col style="width: 30mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
</colgroup>
|
||||
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{%= __(" ") %}</th>
|
||||
<th>{%= __(range1) %}</th>
|
||||
<th>{%= __(range2) %}</th>
|
||||
<th>{%= __(range3) %}</th>
|
||||
<th>{%= __(range4) %}</th>
|
||||
<th>{%= __(range5) %}</th>
|
||||
<th>{%= __("Total") %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{%= __("Total Outstanding") %}</td>
|
||||
<td class="text-right">{%= format_number(balance_row["range1"], null, 2) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row["range2"]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row["range3"]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row["range4"]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row["range5"]) %}</td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row["outstanding"]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
</tr>
|
||||
<td>{%= __("Future Payments") %}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row[("future_amount")]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
<tr class="cvs-footer">
|
||||
<th class="text-left">{%= __("Cheques Required") %}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th class="text-right">
|
||||
{%= format_currency(flt(balance_row["outstanding"] - balance_row[("future_amount")]), data[data.length-1]["currency"]) %}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
{% } %}
|
||||
{% } %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% var balance_row = data.slice(-1).pop();
|
||||
var range1 = report.columns[11].label;
|
||||
var range2 = report.columns[12].label;
|
||||
var range3 = report.columns[13].label;
|
||||
var range4 = report.columns[14].label;
|
||||
var range5 = report.columns[15].label;
|
||||
var range6 = report.columns[16].label;
|
||||
%}
|
||||
{% if(balance_row) { %}
|
||||
<table class="table table-bordered table-condensed">
|
||||
<caption class="text-right">(Amount in {%= data[0][__("currency")] || "" %})</caption>
|
||||
<colgroup>
|
||||
<col style="width: 30mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
<col style="width: 18mm;">
|
||||
</colgroup>
|
||||
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{%= __(" ") %}</th>
|
||||
<th>{%= __(range1) %}</th>
|
||||
<th>{%= __(range2) %}</th>
|
||||
<th>{%= __(range3) %}</th>
|
||||
<th>{%= __(range4) %}</th>
|
||||
<th>{%= __(range5) %}</th>
|
||||
<th>{%= __(range6) %}</th>
|
||||
<th>{%= __("Total") %}</th>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<th style="width: 10%">{%= __("Date") %}</th>
|
||||
<th style="width: 4%">{%= __("Age (Days)") %}</th>
|
||||
|
||||
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
|
||||
<th style="width: 14%">{%= __("Reference") %}</th>
|
||||
<th style="width: 10%">{%= __("Sales Person") %}</th>
|
||||
{% } else { %}
|
||||
<th style="width: 24%">{%= __("Reference") %}</th>
|
||||
{% } %}
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<th style="width: 10%; text-align: right">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 10%; text-align: right">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%; text-align: right">{%= __("Outstanding Amount") %}</th>
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<th style="width: 12%">{%= __("Customer LPO No.") %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%">{%= __("Future Payment Ref") %}</th>
|
||||
<th style="width: 10%">{%= __("Future Payment Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Paid Amount") %}</th>
|
||||
<th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
|
||||
<th style="width: 15%">{%= __("Total Outstanding Amount") %}</th>
|
||||
{% } %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{%= __("Total Outstanding") %}</td>
|
||||
<td class="text-right">{%= format_number(balance_row[range1], null, 2) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range2]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range3]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range4]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range5]) %}</td>
|
||||
<td class="text-right">{%= format_currency(balance_row[range6]) %}</td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row[("outstanding_amount")]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
</tr>
|
||||
<td>{%= __("PDC/LC") %}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
<td class="text-right">
|
||||
{%= format_currency(flt(balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}
|
||||
</td>
|
||||
<tr class="cvs-footer">
|
||||
<th class="text-left">{%= __("Cheques Required") %}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
<th class="text-right">
|
||||
{%= format_currency(flt(balance_row[("outstanding_amount")]-balance_row[("pdc/lc_amount")]), data[data.length-1]["currency"]) %}</th>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
{% } %}
|
||||
{% } %}
|
||||
<table class="table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<th style="width: 10%">{%= __("Date") %}</th>
|
||||
<th style="width: 4%">{%= __("Age (Days)") %}</th>
|
||||
|
||||
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
|
||||
<th style="width: 14%">{%= __("Reference") %}</th>
|
||||
<th style="width: 10%">{%= __("Sales Person") %}</th>
|
||||
{% } else { %}
|
||||
<th style="width: 24%">{%= __("Reference") %}</th>
|
||||
{% } %}
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<th style="width: 20%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%; text-align: right">{%= __("Invoiced Amount") %}</th>
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<th style="width: 10%; text-align: right">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 10%; text-align: right">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%; text-align: right">{%= __("Outstanding Amount") %}</th>
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<th style="width: 12%">{%= __("Customer LPO No.") %}</th>
|
||||
{% } %}
|
||||
<th style="width: 10%">{%= __("PDC/LC Ref") %}</th>
|
||||
<th style="width: 10%">{%= __("PDC/LC Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("Remaining Balance") %}</th>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Paid Amount") %}</th>
|
||||
<th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
|
||||
<th style="width: 15%">{%= __("Total Outstanding Amount") %}</th>
|
||||
{% } %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for(var i=0, l=data.length; i<l; i++) { %}
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]) { %}
|
||||
<td>{%= frappe.datetime.str_to_user(data[i]["posting_date"]) %}</td>
|
||||
<td style="text-align: right">{%= data[i][__("Age (Days)")] %}</td>
|
||||
<td>
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
{%= data[i]["voucher_type"] %}
|
||||
<br>
|
||||
{% } %}
|
||||
{%= data[i]["voucher_no"] %}
|
||||
</td>
|
||||
|
||||
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
|
||||
<td>{%= data[i]["sales_person"] %}</td>
|
||||
{% } %}
|
||||
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
{% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
|
||||
<br> {%= data[i][__("Customer Name")] %}
|
||||
{% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
|
||||
<br> {%= data[i][__("Supplier Name")] %}
|
||||
{% for(var i=0, l=data.length; i<l; i++) { %}
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
{% if(data[i]["party"]) { %}
|
||||
<td>{%= frappe.datetime.str_to_user(data[i]["posting_date"]) %}</td>
|
||||
<td style="text-align: right">{%= data[i]["age"] %}</td>
|
||||
<td>
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
{%= data[i]["voucher_type"] %}
|
||||
<br>
|
||||
{% } %}
|
||||
{%= data[i]["voucher_no"] %}
|
||||
</td>
|
||||
|
||||
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
|
||||
<td>{%= data[i]["sales_person"] %}</td>
|
||||
{% } %}
|
||||
<div>
|
||||
{% if data[i][__("Remarks")] %}
|
||||
{%= __("Remarks") %}:
|
||||
{%= data[i][__("Remarks")] %}
|
||||
{% } %}
|
||||
</div>
|
||||
</td>
|
||||
{% } %}
|
||||
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<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>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i]["po_no"] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<td></td>
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<td></td>
|
||||
{% } %}
|
||||
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
|
||||
<td></td>
|
||||
{% } %}
|
||||
<td></td>
|
||||
<td style="text-align: right"><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["invoiced_amount"], data[i]["currency"] ) %}</td>
|
||||
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<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>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["outstanding_amount"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i][__("Customer LPO")] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= data[i][("pdc/lc_ref")] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("pdc/lc_amount")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("remaining_balance")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %}
|
||||
{% if((data[i][__("Customer")] || data[i][__("Supplier")]) != __("'Total'")) { %}
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
{% if(data[i][__("Customer Name")] && data[i][__("Customer Name")] != data[i][__("Customer")]) { %}
|
||||
<br> {%= data[i][__("Customer Name")] %}
|
||||
{% } else if(data[i][__("Supplier Name")] != data[i][__("Supplier")]) { %}
|
||||
<br> {%= data[i][__("Supplier Name")] %}
|
||||
{%= data[i]["party"] %}
|
||||
{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
|
||||
<br> {%= data[i]["customer_name"] %}
|
||||
{% } else if(data[i]["supplier_name"] != data[i]["party"]) { %}
|
||||
<br> {%= data[i]["supplier_name"] %}
|
||||
{% } %}
|
||||
{% } %}
|
||||
<br>{%= __("Remarks") %}:
|
||||
{%= data[i][__("Remarks")] %}
|
||||
<div>
|
||||
{% if data[i]["remarks"] %}
|
||||
{%= __("Remarks") %}:
|
||||
{%= data[i]["remarks"] %}
|
||||
{% } %}
|
||||
</div>
|
||||
</td>
|
||||
{% } %}
|
||||
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i]["po_no"] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= data[i]["future_ref"] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
<td></td>
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<td></td>
|
||||
{% } %}
|
||||
{% if(report.report_name === "Accounts Receivable" && filters.show_sales_person) { %}
|
||||
<td></td>
|
||||
{% } %}
|
||||
<td></td>
|
||||
<td style="text-align: right"><b>{%= __("Total") %}</b></td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["invoiced"], data[i]["currency"] ) %}</td>
|
||||
|
||||
{% if(!filters.show_future_payments) { %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %} </td>
|
||||
{% } %}
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
|
||||
|
||||
{% if(filters.show_future_payments) { %}
|
||||
{% if(report.report_name === "Accounts Receivable") { %}
|
||||
<td style="text-align: right">
|
||||
{%= data[i]["po_no"] %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= data[i]["future_ref"] %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["future_amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["remaining_balance"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
{% } %}
|
||||
{% } else { %}
|
||||
{% if(data[i]["party"]|| " ") { %}
|
||||
{% if((data[i]["party"]) != __("'Total'")) { %}
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i]["party"] %}
|
||||
{% if(data[i]["customer_name"] && data[i]["customer_name"] != data[i]["party"]) { %}
|
||||
<br> {%= data[i]["customer_name"] %}
|
||||
{% } else if(data[i]["supplier_name"] != data[i]["party"]) { %}
|
||||
<br> {%= data[i]["supplier_name"] %}
|
||||
{% } %}
|
||||
{% } %}
|
||||
<br>{%= __("Remarks") %}:
|
||||
{%= data[i]["remarks"] %}
|
||||
</td>
|
||||
{% } else { %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= format_currency(data[i]["invoiced"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["paid"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["credit_note"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i]["outstanding"], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
<td style="text-align: right">{%= format_currency(data[i][("total_invoiced_amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("total_paid_amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= report.report_name === "Accounts Receivable Summary" ? format_currency(data[i][__("credit_note_amt")], data[i]["currency"]) : format_currency(data[i][__("debit_note_amt")], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">{%= format_currency(data[i][("total_outstanding_amt")], data[i]["currency"]) %}</td>
|
||||
{% } %}
|
||||
</tr>
|
||||
{% } %}
|
||||
</tr>
|
||||
{% } %}
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-right text-muted">{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
|
||||
</tbody>
|
||||
</table>
|
||||
<p class="text-right text-muted">{{ __("Printed On ") }}{%= frappe.datetime.str_to_user(frappe.datetime.get_datetime_as_string()) %}</p>
|
||||
|
||||
@@ -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:
|
||||
@@ -364,7 +376,7 @@ class ReceivablePayableReport(object):
|
||||
on
|
||||
(ref.parent = payment_entry.name)
|
||||
where
|
||||
payment_entry.docstatus = 1
|
||||
payment_entry.docstatus < 2
|
||||
and payment_entry.posting_date > %s
|
||||
and payment_entry.party_type = %s
|
||||
""", (self.filters.report_date, self.party_type), as_dict=1)
|
||||
@@ -389,7 +401,7 @@ class ReceivablePayableReport(object):
|
||||
on
|
||||
(jea.parent = je.name)
|
||||
where
|
||||
je.docstatus = 1
|
||||
je.docstatus < 2
|
||||
and je.posting_date > %s
|
||||
and jea.party_type = %s
|
||||
and jea.reference_name is not null and jea.reference_name != ''
|
||||
@@ -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
|
||||
@@ -445,6 +470,10 @@ class ReceivablePayableReport(object):
|
||||
|
||||
row.age = (getdate(self.age_as_on) - getdate(entry_date)).days or 0
|
||||
index = None
|
||||
|
||||
if not (self.filters.range1 and self.filters.range2 and self.filters.range3 and self.filters.range4):
|
||||
self.filters.range1, self.filters.range2, self.filters.range3, self.filters.range4 = 30, 60, 90, 120
|
||||
|
||||
for i, days in enumerate([self.filters.range1, self.filters.range2, self.filters.range3, self.filters.range4]):
|
||||
if row.age <= days:
|
||||
index = i
|
||||
@@ -673,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": {
|
||||
@@ -685,4 +714,4 @@ class ReceivablePayableReport(object):
|
||||
'datasets': rows
|
||||
},
|
||||
"type": 'percentage'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,7 +40,8 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
||||
|
||||
row.party = party
|
||||
if self.party_naming_by == "Naming Series":
|
||||
row.party_name = frappe.get_cached_value(self.party_type, party, [self.party_type + "_name"])
|
||||
row.party_name = frappe.get_cached_value(self.party_type,
|
||||
party, frappe.scrub(self.party_type) + "_name")
|
||||
|
||||
row.update(party_dict)
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
||||
section_data.append(net_profit_loss)
|
||||
|
||||
for account in cash_flow_account['account_types']:
|
||||
account_data = get_account_type_based_data(account['account_type'], companies, fiscal_year)
|
||||
account_data = get_account_type_based_data(account['account_type'], companies, fiscal_year, filters)
|
||||
account_data.update({
|
||||
"account_name": account['label'],
|
||||
"account": account['label'],
|
||||
@@ -148,12 +148,12 @@ def get_cash_flow_data(fiscal_year, companies, filters):
|
||||
|
||||
return data
|
||||
|
||||
def get_account_type_based_data(account_type, companies, fiscal_year):
|
||||
def get_account_type_based_data(account_type, companies, fiscal_year, filters):
|
||||
data = {}
|
||||
total = 0
|
||||
for company in companies:
|
||||
amount = get_account_type_based_gl_data(company,
|
||||
fiscal_year.year_start_date, fiscal_year.year_end_date, account_type)
|
||||
fiscal_year.year_start_date, fiscal_year.year_end_date, account_type, filters)
|
||||
|
||||
if amount and account_type == "Depreciation":
|
||||
amount *= -1
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -27,8 +27,8 @@ frappe.query_reports["Payment Period Based On Invoice Date"] = {
|
||||
fieldname:"payment_type",
|
||||
label: __("Payment Type"),
|
||||
fieldtype: "Select",
|
||||
options: "Incoming\nOutgoing",
|
||||
default: "Incoming"
|
||||
options: __("Incoming")+"\n"+__("Outgoing"),
|
||||
default: __("Incoming")
|
||||
},
|
||||
{
|
||||
"fieldname":"party_type",
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from erpnext.accounts.report.accounts_receivable.accounts_receivable import get_ageing_data
|
||||
from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
|
||||
from frappe.utils import getdate, flt
|
||||
|
||||
def execute(filters=None):
|
||||
if not filters: filters = {}
|
||||
if not filters:
|
||||
filters = {}
|
||||
|
||||
validate_filters(filters)
|
||||
|
||||
columns = get_columns(filters)
|
||||
@@ -19,18 +21,29 @@ def execute(filters=None):
|
||||
for d in entries:
|
||||
invoice = invoice_details.get(d.against_voucher) or frappe._dict()
|
||||
|
||||
if d.reference_type=="Purchase Invoice":
|
||||
if d.reference_type == "Purchase Invoice":
|
||||
payment_amount = flt(d.debit) or -1 * flt(d.credit)
|
||||
|
||||
else:
|
||||
payment_amount = flt(d.credit) or -1 * flt(d.debit)
|
||||
|
||||
row = [d.voucher_type, d.voucher_no, d.party_type, d.party, d.posting_date, d.against_voucher,
|
||||
invoice.posting_date, invoice.due_date, d.debit, d.credit, d.remarks]
|
||||
d.update({
|
||||
"range1": 0,
|
||||
"range2": 0,
|
||||
"range3": 0,
|
||||
"range4": 0,
|
||||
"outstanding": payment_amount
|
||||
})
|
||||
|
||||
if d.against_voucher:
|
||||
row += get_ageing_data(30, 60, 90, 120, d.posting_date, invoice.posting_date, payment_amount)
|
||||
else:
|
||||
row += ["", "", "", "", ""]
|
||||
ReceivablePayableReport(filters).get_ageing_data(invoice.posting_date, d)
|
||||
|
||||
row = [
|
||||
d.voucher_type, d.voucher_no, d.party_type, d.party, d.posting_date, d.against_voucher,
|
||||
invoice.posting_date, invoice.due_date, d.debit, d.credit, d.remarks,
|
||||
d.age, d.range1, d.range2, d.range3, d.range4
|
||||
]
|
||||
|
||||
if invoice.due_date:
|
||||
row.append((getdate(d.posting_date) - getdate(invoice.due_date)).days or 0)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -286,12 +286,6 @@ class Asset(AccountsController):
|
||||
if self.status not in ("Submitted", "Partially Depreciated", "Fully Depreciated"):
|
||||
frappe.throw(_("Asset cannot be cancelled, as it is already {0}").format(self.status))
|
||||
|
||||
if self.purchase_invoice:
|
||||
frappe.throw(_("Please cancel Purchase Invoice {0} first").format(self.purchase_invoice))
|
||||
|
||||
if self.purchase_receipt:
|
||||
frappe.throw(_("Please cancel Purchase Receipt {0} first").format(self.purchase_receipt))
|
||||
|
||||
def delete_depreciation_entries(self):
|
||||
for d in self.get("schedules"):
|
||||
if d.journal_entry:
|
||||
|
||||
@@ -56,8 +56,7 @@ def assign_tasks(asset_maintenance_name, assign_to_member, maintenance_task, nex
|
||||
def calculate_next_due_date(periodicity, start_date = None, end_date = None, last_completion_date = None, next_due_date = None):
|
||||
if not start_date and not last_completion_date:
|
||||
start_date = frappe.utils.now()
|
||||
|
||||
if last_completion_date and (last_completion_date > start_date or not start_date):
|
||||
if last_completion_date and ((start_date and last_completion_date > start_date) or not start_date):
|
||||
start_date = last_completion_date
|
||||
if periodicity == 'Daily':
|
||||
next_due_date = add_days(start_date, 1)
|
||||
@@ -115,4 +114,4 @@ def get_maintenance_log(asset_name):
|
||||
select maintenance_status, count(asset_name) as count, asset_name
|
||||
from `tabAsset Maintenance Log`
|
||||
where asset_name=%s group by maintenance_status""",
|
||||
(asset_name), as_dict=1)
|
||||
(asset_name), as_dict=1)
|
||||
|
||||
@@ -10,7 +10,8 @@ frappe.ui.form.on("Purchase Order", {
|
||||
frm.custom_make_buttons = {
|
||||
'Purchase Receipt': 'Receipt',
|
||||
'Purchase Invoice': 'Invoice',
|
||||
'Stock Entry': 'Material to Supplier'
|
||||
'Stock Entry': 'Material to Supplier',
|
||||
'Payment Entry': 'Payment'
|
||||
}
|
||||
|
||||
frm.set_query("reserve_warehouse", "supplied_items", function() {
|
||||
|
||||
@@ -87,7 +87,7 @@ class AccountsController(TransactionBase):
|
||||
self.validate_currency()
|
||||
|
||||
if self.doctype == 'Purchase Invoice':
|
||||
self.validate_paid_amount()
|
||||
self.calculate_paid_amount()
|
||||
|
||||
if self.doctype in ['Purchase Invoice', 'Sales Invoice']:
|
||||
pos_check_field = "is_pos" if self.doctype=="Sales Invoice" else "is_paid"
|
||||
@@ -131,22 +131,23 @@ class AccountsController(TransactionBase):
|
||||
else:
|
||||
df.set("print_hide", 1)
|
||||
|
||||
def validate_paid_amount(self):
|
||||
def calculate_paid_amount(self):
|
||||
if hasattr(self, "is_pos") or hasattr(self, "is_paid"):
|
||||
is_paid = self.get("is_pos") or self.get("is_paid")
|
||||
if cint(is_paid) == 1:
|
||||
if flt(self.paid_amount) == 0 and flt(self.outstanding_amount) > 0:
|
||||
if self.cash_bank_account:
|
||||
self.paid_amount = flt(flt(self.outstanding_amount), self.precision("paid_amount"))
|
||||
self.base_paid_amount = flt(self.paid_amount * self.conversion_rate,
|
||||
self.precision("base_paid_amount"))
|
||||
else:
|
||||
# show message that the amount is not paid
|
||||
self.paid_amount = 0
|
||||
frappe.throw(
|
||||
_("Note: Payment Entry will not be created since 'Cash or Bank Account' was not specified"))
|
||||
else:
|
||||
frappe.db.set(self, 'paid_amount', 0)
|
||||
|
||||
if is_paid:
|
||||
if not self.cash_bank_account:
|
||||
# show message that the amount is not paid
|
||||
frappe.throw(_("Note: Payment Entry will not be created since 'Cash or Bank Account' was not specified"))
|
||||
|
||||
if cint(self.is_return) and (self.grand_total > self.paid_amount):
|
||||
self.paid_amount = flt(flt(self.grand_total), self.precision("paid_amount"))
|
||||
|
||||
elif not flt(self.paid_amount) and flt(self.outstanding_amount) > 0:
|
||||
self.paid_amount = flt(flt(self.outstanding_amount), self.precision("paid_amount"))
|
||||
|
||||
self.base_paid_amount = flt(self.paid_amount * self.conversion_rate,
|
||||
self.precision("base_paid_amount"))
|
||||
|
||||
def set_missing_values(self, for_validate=False):
|
||||
if frappe.flags.in_test:
|
||||
|
||||
@@ -337,7 +337,7 @@ class BuyingController(StockController):
|
||||
if self.doctype in ["Purchase Receipt", "Purchase Invoice"]:
|
||||
rm.consumed_qty = required_qty
|
||||
rm.description = bom_item.description
|
||||
if item.batch_no and not rm.batch_no:
|
||||
if item.batch_no and frappe.db.get_value("Item", rm.rm_item_code, "has_batch_no") and not rm.batch_no:
|
||||
rm.batch_no = item.batch_no
|
||||
|
||||
# get raw materials rate
|
||||
|
||||
@@ -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"""
|
||||
|
||||
@@ -246,6 +246,8 @@ def make_return_doc(doctype, source_name, target_doc=None):
|
||||
elif doc.doctype == 'Purchase Invoice':
|
||||
doc.paid_amount = -1 * source.paid_amount
|
||||
doc.base_paid_amount = -1 * source.base_paid_amount
|
||||
doc.payment_terms_template = ''
|
||||
doc.payment_schedule = []
|
||||
|
||||
if doc.get("is_return") and hasattr(doc, "packed_items"):
|
||||
for d in doc.get("packed_items"):
|
||||
|
||||
@@ -39,7 +39,6 @@ def validate_filters(filters):
|
||||
frappe.throw(_("'Based On' and 'Group By' can not be same"))
|
||||
|
||||
def get_data(filters, conditions):
|
||||
|
||||
data = []
|
||||
inc, cond= '',''
|
||||
query_details = conditions["based_on_select"] + conditions["period_wise_select"]
|
||||
@@ -47,13 +46,17 @@ def get_data(filters, conditions):
|
||||
posting_date = 't1.transaction_date'
|
||||
if conditions.get('trans') in ['Sales Invoice', 'Purchase Invoice', 'Purchase Receipt', 'Delivery Note']:
|
||||
posting_date = 't1.posting_date'
|
||||
if filters.period_based_on:
|
||||
posting_date = 't1.'+filters.period_based_on
|
||||
|
||||
if conditions["based_on_select"] in ["t1.project,", "t2.project,"]:
|
||||
cond = ' and '+ conditions["based_on_select"][:-1] +' IS Not NULL'
|
||||
|
||||
if conditions.get('trans') in ['Sales Order', 'Purchase Order']:
|
||||
cond += " and t1.status != 'Closed'"
|
||||
|
||||
if conditions.get('trans') == 'Quotation' and filters.get("group_by") == 'Customer':
|
||||
cond += " and t1.quotation_to = 'Customer'"
|
||||
|
||||
year_start_date, year_end_date = frappe.db.get_value("Fiscal Year",
|
||||
filters.get('fiscal_year'), ["year_start_date", "year_end_date"])
|
||||
|
||||
@@ -64,7 +67,7 @@ def get_data(filters, conditions):
|
||||
if filters.get("group_by") == 'Item':
|
||||
sel_col = 't2.item_code'
|
||||
elif filters.get("group_by") == 'Customer':
|
||||
sel_col = 't1.customer'
|
||||
sel_col = 't1.party_name' if conditions.get('trans') == 'Quotation' else 't1.customer'
|
||||
elif filters.get("group_by") == 'Supplier':
|
||||
sel_col = 't1.supplier'
|
||||
|
||||
@@ -225,7 +228,7 @@ def based_wise_columns_query(based_on, trans):
|
||||
elif based_on == "Customer":
|
||||
based_on_details["based_on_cols"] = ["Customer:Link/Customer:120", "Territory:Link/Territory:120"]
|
||||
based_on_details["based_on_select"] = "t1.customer_name, t1.territory, "
|
||||
based_on_details["based_on_group_by"] = 't1.customer'
|
||||
based_on_details["based_on_group_by"] = 't1.party_name' if trans == 'Quotation' else 't1.customer'
|
||||
based_on_details["addl_tables"] = ''
|
||||
|
||||
elif based_on == "Customer Group":
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -62,7 +62,8 @@ def _order(*args, **kwargs):
|
||||
|
||||
item_woo_com_id = item.get("product_id")
|
||||
|
||||
if frappe.get_value("Item",{"woocommerce_id": item_woo_com_id}):
|
||||
if frappe.get_value("Item",{"woocommerce_id": item_woo_com_id}) or\
|
||||
frappe.get_value("Item",{"item_name": item.get('name')}):
|
||||
#Edit
|
||||
link_item(item,1)
|
||||
else:
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cint, cstr, getdate
|
||||
from frappe.utils import cint, cstr, getdate, flt
|
||||
import dateutil
|
||||
from frappe.model.naming import set_name_by_naming_series
|
||||
from erpnext.healthcare.doctype.healthcare_settings.healthcare_settings import get_receivable_account,get_income_account,send_registration_sms
|
||||
@@ -64,7 +64,7 @@ class Patient(Document):
|
||||
def invoice_patient_registration(self):
|
||||
frappe.db.set_value("Patient", self.name, "disabled", 0)
|
||||
send_registration_sms(self)
|
||||
if(frappe.get_value("Healthcare Settings", None, "registration_fee")>0):
|
||||
if(flt(frappe.get_value("Healthcare Settings", None, "registration_fee"))>0):
|
||||
company = frappe.defaults.get_user_default('company')
|
||||
if not company:
|
||||
company = frappe.db.get_value("Global Defaults", None, "default_company")
|
||||
|
||||
@@ -648,7 +648,7 @@ def get_bom_items_as_dict(bom, company, qty=1, fetch_exploded=1, fetch_scrap_ite
|
||||
item_dict[key] = item
|
||||
|
||||
for item, item_details in item_dict.items():
|
||||
for d in [["Account", "expense_account", "default_expense_account"],
|
||||
for d in [["Account", "expense_account", "stock_adjustment_account"],
|
||||
["Cost Center", "cost_center", "cost_center"], ["Warehouse", "default_warehouse", ""]]:
|
||||
company_in_record = frappe.db.get_value(d[0], item_details.get(d[1]), "company")
|
||||
if not item_details.get(d[1]) or (company_in_record and company != company_in_record):
|
||||
|
||||
@@ -105,7 +105,6 @@ class JobCard(Document):
|
||||
for_quantity, time_in_mins = 0, 0
|
||||
from_time_list, to_time_list = [], []
|
||||
|
||||
|
||||
for d in frappe.get_all('Job Card',
|
||||
filters = {'docstatus': 1, 'operation_id': self.operation_id}):
|
||||
doc = frappe.get_doc('Job Card', d.name)
|
||||
@@ -125,8 +124,8 @@ class JobCard(Document):
|
||||
if data.name == self.operation_id:
|
||||
data.completed_qty = for_quantity
|
||||
data.actual_operation_time = time_in_mins
|
||||
data.actual_start_time = min(from_time_list)
|
||||
data.actual_end_time = max(to_time_list)
|
||||
data.actual_start_time = min(from_time_list) if from_time_list else None
|
||||
data.actual_end_time = max(to_time_list) if to_time_list else None
|
||||
|
||||
wo.flags.ignore_validate_update_after_submit = True
|
||||
wo.update_operation_status()
|
||||
|
||||
@@ -97,7 +97,7 @@ class ProductionPlan(Document):
|
||||
self.get_mr_items()
|
||||
|
||||
def get_so_items(self):
|
||||
so_list = [d.sales_order for d in self.sales_orders if d.sales_order]
|
||||
so_list = [d.sales_order for d in self.get("sales_orders", []) if d.sales_order]
|
||||
if not so_list:
|
||||
msgprint(_("Please enter Sales Orders in the above table"))
|
||||
return []
|
||||
@@ -132,7 +132,7 @@ class ProductionPlan(Document):
|
||||
self.calculate_total_planned_qty()
|
||||
|
||||
def get_mr_items(self):
|
||||
mr_list = [d.material_request for d in self.material_requests if d.material_request]
|
||||
mr_list = [d.material_request for d in self.get("material_requests", []) if d.material_request]
|
||||
if not mr_list:
|
||||
msgprint(_("Please enter Material Requests in the above table"))
|
||||
return []
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -147,6 +147,15 @@ frappe.ui.form.on("Timesheet Detail", {
|
||||
calculate_time_and_amount(frm);
|
||||
},
|
||||
|
||||
task: (frm, cdt, cdn) => {
|
||||
let row = frm.selected_doc;
|
||||
if (row.task) {
|
||||
frappe.db.get_value("Task", row.task, "project", (r) => {
|
||||
frappe.model.set_value(cdt, cdn, "project", r.project);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
from_time: function(frm, cdt, cdn) {
|
||||
calculate_end_time(frm, cdt, cdn);
|
||||
},
|
||||
@@ -200,9 +209,6 @@ frappe.ui.form.on("Timesheet Detail", {
|
||||
},
|
||||
|
||||
activity_type: function(frm, cdt, cdn) {
|
||||
frm.script_manager.copy_from_first_row('time_logs', frm.selected_doc,
|
||||
'project');
|
||||
|
||||
frappe.call({
|
||||
method: "erpnext.projects.doctype.timesheet.timesheet.get_activity_cost",
|
||||
args: {
|
||||
|
||||
@@ -148,12 +148,17 @@ class Timesheet(Document):
|
||||
def validate_time_logs(self):
|
||||
for data in self.get('time_logs'):
|
||||
self.validate_overlap(data)
|
||||
self.validate_task_project()
|
||||
|
||||
def validate_overlap(self, data):
|
||||
settings = frappe.get_single('Projects Settings')
|
||||
self.validate_overlap_for("user", data, self.user, settings.ignore_user_time_overlap)
|
||||
self.validate_overlap_for("employee", data, self.employee, settings.ignore_employee_time_overlap)
|
||||
|
||||
def validate_task_project(self):
|
||||
for log in self.time_logs:
|
||||
log.project = log.project or frappe.db.get_value("Task", log.task, "project")
|
||||
|
||||
def validate_overlap_for(self, fieldname, args, value, ignore_validation=False):
|
||||
if not value or ignore_validation:
|
||||
return
|
||||
|
||||
@@ -41,6 +41,12 @@ erpnext.taxes_and_totals = erpnext.payments.extend({
|
||||
this.calculate_contribution();
|
||||
}
|
||||
|
||||
// Update paid amount on return/debit note creation
|
||||
if(this.frm.doc.doctype === "Purchase Invoice" && this.frm.doc.is_return
|
||||
&& (this.frm.doc.grand_total > this.frm.doc.paid_amount)) {
|
||||
this.frm.doc.paid_amount = flt(this.frm.doc.grand_total, precision("grand_total"));
|
||||
}
|
||||
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
|
||||
@@ -3,6 +3,14 @@
|
||||
|
||||
erpnext.get_purchase_trends_filters = function() {
|
||||
return [
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"reqd": 1,
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
{
|
||||
"fieldname":"period",
|
||||
"label": __("Period"),
|
||||
@@ -15,6 +23,23 @@ erpnext.get_purchase_trends_filters = function() {
|
||||
],
|
||||
"default": "Monthly"
|
||||
},
|
||||
{
|
||||
"fieldname":"fiscal_year",
|
||||
"label": __("Fiscal Year"),
|
||||
"fieldtype": "Link",
|
||||
"options":'Fiscal Year',
|
||||
"default": frappe.sys_defaults.fiscal_year
|
||||
},
|
||||
{
|
||||
"fieldname":"period_based_on",
|
||||
"label": __("Period based On"),
|
||||
"fieldtype": "Select",
|
||||
"options": [
|
||||
{ "value": "posting_date", "label": __("Posting Date") },
|
||||
{ "value": "bill_date", "label": __("Billing Date") },
|
||||
],
|
||||
"default": "posting_date"
|
||||
},
|
||||
{
|
||||
"fieldname":"based_on",
|
||||
"label": __("Based On"),
|
||||
@@ -39,19 +64,5 @@ erpnext.get_purchase_trends_filters = function() {
|
||||
],
|
||||
"default": ""
|
||||
},
|
||||
{
|
||||
"fieldname":"fiscal_year",
|
||||
"label": __("Fiscal Year"),
|
||||
"fieldtype": "Link",
|
||||
"options":'Fiscal Year',
|
||||
"default": frappe.sys_defaults.fiscal_year
|
||||
},
|
||||
{
|
||||
"fieldname":"company",
|
||||
"label": __("Company"),
|
||||
"fieldtype": "Link",
|
||||
"options": "Company",
|
||||
"default": frappe.defaults.get_user_default("Company")
|
||||
},
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -70,8 +70,9 @@ $.extend(erpnext, {
|
||||
"get_query": function () {
|
||||
return {
|
||||
filters: {
|
||||
item_code:grid_row.doc.item_code,
|
||||
warehouse:cur_frm.doc.is_return ? null : grid_row.doc.warehouse
|
||||
item_code: grid_row.doc.item_code,
|
||||
warehouse: cur_frm.doc.is_return ? null : grid_row.doc.warehouse,
|
||||
batch_no: grid_row.doc.batch_no || null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
{%- macro format_float(value) -%}
|
||||
{%- macro format_float(value, precision=2) -%}
|
||||
{%- if frappe.utils.cint(precision) == 3 %}
|
||||
{{ "%.3f" % value|abs }}
|
||||
{%- elif frappe.utils.cint(precision) == 4 -%}
|
||||
{{ "%.4f" % value|abs }}
|
||||
{%- else -%}
|
||||
{{ "%.2f" % value|abs }}
|
||||
{%- endif %}
|
||||
{%- endmacro -%}
|
||||
|
||||
{%- macro render_address(address) %}
|
||||
@@ -182,10 +188,10 @@
|
||||
<Descrizione>{{ html2text(item.description or '') or item.item_name }}</Descrizione>
|
||||
<Quantita>{{ format_float(item.qty) }}</Quantita>
|
||||
<UnitaMisura>{{ item.stock_uom }}</UnitaMisura>
|
||||
<PrezzoUnitario>{{ format_float(item.price_list_rate or item.rate) }}</PrezzoUnitario>
|
||||
<PrezzoUnitario>{{ format_float(item.price_list_rate or item.rate, item_meta.get_field("rate").precision) }}</PrezzoUnitario>
|
||||
{{ render_discount_or_margin(item) }}
|
||||
<PrezzoTotale>{{ format_float(item.amount) }}</PrezzoTotale>
|
||||
<AliquotaIVA>{{ format_float(item.tax_rate) }}</AliquotaIVA>
|
||||
<PrezzoTotale>{{ format_float(item.amount, item_meta.get_field("amount").precision) }}</PrezzoTotale>
|
||||
<AliquotaIVA>{{ format_float(item.tax_rate, item_meta.get_field("tax_rate").precision) }}</AliquotaIVA>
|
||||
{%- if item.tax_exemption_reason %}
|
||||
<Natura>{{ item.tax_exemption_reason.split("-")[0] }}</Natura>
|
||||
{%- endif %}
|
||||
@@ -197,8 +203,8 @@
|
||||
{%- if data.tax_exemption_reason %}
|
||||
<Natura>{{ data.tax_exemption_reason.split("-")[0] }}</Natura>
|
||||
{%- endif %}
|
||||
<ImponibileImporto>{{ format_float(data.taxable_amount) }}</ImponibileImporto>
|
||||
<Imposta>{{ format_float(data.tax_amount) }}</Imposta>
|
||||
<ImponibileImporto>{{ format_float(data.taxable_amount, item_meta.get_field("tax_amount").precision) }}</ImponibileImporto>
|
||||
<Imposta>{{ format_float(data.tax_amount, item_meta.get_field("tax_amount").precision) }}</Imposta>
|
||||
<EsigibilitaIVA>{{ doc.vat_collectability.split("-")[0] }}</EsigibilitaIVA>
|
||||
{%- if data.tax_exemption_law %}
|
||||
<RiferimentoNormativo>{{ data.tax_exemption_law }}</RiferimentoNormativo>
|
||||
|
||||
@@ -188,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})
|
||||
@@ -290,7 +294,11 @@ def prepare_and_attach_invoice(doc, replace=False):
|
||||
progressive_name, progressive_number = get_progressive_name_and_number(doc, replace)
|
||||
|
||||
invoice = prepare_invoice(doc, progressive_number)
|
||||
invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml', context={"doc": invoice}, is_path=True)
|
||||
item_meta = frappe.get_meta("Sales Invoice Item")
|
||||
|
||||
invoice_xml = frappe.render_template('erpnext/regional/italy/e-invoice.xml',
|
||||
context={"doc": invoice, "item_meta": item_meta}, is_path=True)
|
||||
|
||||
invoice_xml = invoice_xml.replace("&", "&")
|
||||
|
||||
xml_filename = progressive_name + ".xml"
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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'),
|
||||
|
||||
@@ -10,7 +10,8 @@ frappe.ui.form.on("Sales Order", {
|
||||
'Sales Invoice': 'Invoice',
|
||||
'Material Request': 'Material Request',
|
||||
'Purchase Order': 'Purchase Order',
|
||||
'Project': 'Project'
|
||||
'Project': 'Project',
|
||||
'Payment Entry': "Payment"
|
||||
}
|
||||
frm.add_fetch('customer', 'tax_id', 'tax_id');
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -40,6 +40,16 @@ class Analytics(object):
|
||||
"fieldtype": "Data",
|
||||
"width": 140
|
||||
})
|
||||
|
||||
if self.filters.tree_type == "Item":
|
||||
self.columns.append({
|
||||
"label": _("UOM"),
|
||||
"fieldname": 'stock_uom',
|
||||
"fieldtype": "Link",
|
||||
"options": "UOM",
|
||||
"width": 100
|
||||
})
|
||||
|
||||
for end_date in self.periodic_daterange:
|
||||
period = self.get_period(end_date)
|
||||
self.columns.append({
|
||||
@@ -107,7 +117,7 @@ class Analytics(object):
|
||||
value_field = 'qty'
|
||||
|
||||
self.entries = frappe.db.sql("""
|
||||
select i.item_code as entity, i.item_name as entity_name, i.{value_field} as value_field, s.{date_field}
|
||||
select i.item_code as entity, i.item_name as entity_name, i.stock_uom, i.{value_field} as value_field, s.{date_field}
|
||||
from `tab{doctype} Item` i , `tab{doctype}` s
|
||||
where s.name = i.parent and i.docstatus = 1 and s.company = %s
|
||||
and s.{date_field} between %s and %s
|
||||
@@ -176,6 +186,10 @@ class Analytics(object):
|
||||
total += amount
|
||||
|
||||
row["total"] = total
|
||||
|
||||
if self.filters.tree_type == "Item":
|
||||
row["stock_uom"] = period_data.get("stock_uom")
|
||||
|
||||
self.data.append(row)
|
||||
|
||||
def get_rows_by_group(self):
|
||||
@@ -210,6 +224,9 @@ class Analytics(object):
|
||||
self.entity_periodic_data.setdefault(d.entity, frappe._dict()).setdefault(period, 0.0)
|
||||
self.entity_periodic_data[d.entity][period] += flt(d.value_field)
|
||||
|
||||
if self.filters.tree_type == "Item":
|
||||
self.entity_periodic_data[d.entity]['stock_uom'] = d.stock_uom
|
||||
|
||||
def get_period(self, posting_date):
|
||||
if self.filters.range == 'Weekly':
|
||||
period = "Week " + str(posting_date.isocalendar()[1]) + " " + str(posting_date.year)
|
||||
|
||||
@@ -209,7 +209,7 @@ erpnext.selling.SellingController = erpnext.TransactionController.extend({
|
||||
args: {
|
||||
item_code: item.item_code,
|
||||
warehouse: item.warehouse,
|
||||
has_batch_no: has_batch_no,
|
||||
has_batch_no: has_batch_no || 0,
|
||||
stock_qty: item.stock_qty,
|
||||
serial_no: item.serial_no || "",
|
||||
},
|
||||
|
||||
@@ -151,7 +151,7 @@ class NamingSeries(Document):
|
||||
|
||||
def insert_series(self, series):
|
||||
"""insert series if missing"""
|
||||
if not frappe.db.get_value('Series', series, 'name', order_by="name"):
|
||||
if frappe.db.get_value('Series', series, 'name', order_by="name") == None:
|
||||
frappe.db.sql("insert into tabSeries (name, current) values (%s, 0)", (series))
|
||||
|
||||
def update_series_start(self):
|
||||
|
||||
@@ -287,19 +287,20 @@ def set_price_list_and_rate(quotation, cart_settings):
|
||||
|
||||
def _set_price_list(quotation, cart_settings):
|
||||
"""Set price list based on customer or shopping cart default"""
|
||||
if quotation.selling_price_list:
|
||||
return
|
||||
from erpnext.accounts.party import get_default_price_list
|
||||
|
||||
# check if customer price list exists
|
||||
selling_price_list = None
|
||||
if quotation.party_name:
|
||||
from erpnext.accounts.party import get_default_price_list
|
||||
selling_price_list = get_default_price_list(frappe.get_doc("Customer", quotation.party_name))
|
||||
selling_price_list = frappe.db.get_value('Customer', quotation.party_name, 'default_price_list')
|
||||
|
||||
# else check for territory based price list
|
||||
if not selling_price_list:
|
||||
selling_price_list = cart_settings.price_list
|
||||
|
||||
if not selling_price_list and quotation.party_name:
|
||||
selling_price_list = get_default_price_list(frappe.get_doc("Customer", quotation.party_name))
|
||||
|
||||
quotation.selling_price_list = selling_price_list
|
||||
|
||||
def set_taxes(quotation, cart_settings):
|
||||
|
||||
@@ -340,7 +340,7 @@ def get_directions(route, optimize):
|
||||
try:
|
||||
directions = maps_client.directions(**directions_data)
|
||||
except Exception as e:
|
||||
frappe.throw(_(e.message))
|
||||
frappe.throw(_(e))
|
||||
|
||||
return directions[0] if directions else False
|
||||
|
||||
|
||||
@@ -32,10 +32,16 @@ class ItemPrice(Document):
|
||||
|
||||
def update_price_list_details(self):
|
||||
if self.price_list:
|
||||
self.buying, self.selling, self.currency = \
|
||||
frappe.db.get_value("Price List",
|
||||
{"name": self.price_list, "enabled": 1},
|
||||
["buying", "selling", "currency"])
|
||||
price_list_details = frappe.db.get_value("Price List",
|
||||
{"name": self.price_list, "enabled": 1},
|
||||
["buying", "selling", "currency"])
|
||||
|
||||
if not price_list_details:
|
||||
link = frappe.utils.get_link_to_form('Price List', self.price_list)
|
||||
frappe.throw("The price list {0} does not exists or disabled".
|
||||
format(link))
|
||||
|
||||
self.buying, self.selling, self.currency = price_list_details
|
||||
|
||||
def update_item_details(self):
|
||||
if self.item_code:
|
||||
|
||||
@@ -10,7 +10,7 @@ cur_frm.fields_dict['delivery_note'].get_query = function(doc, cdt, cdn) {
|
||||
|
||||
cur_frm.fields_dict['items'].grid.get_field('item_code').get_query = function(doc, cdt, cdn) {
|
||||
if(!doc.delivery_note) {
|
||||
frappe.throw(__("Please Delivery Note first"))
|
||||
frappe.throw(__("Please select a Delivery Note"));
|
||||
} else {
|
||||
return {
|
||||
query: "erpnext.stock.doctype.packing_slip.packing_slip.item_details",
|
||||
@@ -125,4 +125,4 @@ cur_frm.pformat.gross_weight_pkg= function(doc){
|
||||
return '<table style="width:100%">' + make_row('Gross Weight', doc.gross_weight_pkg) + '</table>'
|
||||
}
|
||||
|
||||
// TODO: validate gross weight field
|
||||
// TODO: validate gross weight field
|
||||
|
||||
@@ -248,7 +248,7 @@
|
||||
"description": "Identification of the package for the delivery (for print)",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "from_case_no",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -313,7 +313,7 @@
|
||||
"description": "If more than one package of the same type (for print)",
|
||||
"fetch_if_empty": 0,
|
||||
"fieldname": "to_case_no",
|
||||
"fieldtype": "Data",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -773,7 +773,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2019-05-30 21:50:38.260908",
|
||||
"modified": "2019-09-09 12:40:22.497613",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Stock",
|
||||
"name": "Packing Slip",
|
||||
|
||||
@@ -49,11 +49,10 @@ class PackingSlip(Document):
|
||||
frappe.msgprint(_("Please specify a valid 'From Case No.'"), raise_exception=1)
|
||||
elif not self.to_case_no:
|
||||
self.to_case_no = self.from_case_no
|
||||
elif self.from_case_no > self.to_case_no:
|
||||
elif cint(self.from_case_no) > cint(self.to_case_no):
|
||||
frappe.msgprint(_("'To Case No.' cannot be less than 'From Case No.'"),
|
||||
raise_exception=1)
|
||||
|
||||
|
||||
res = frappe.db.sql("""SELECT name FROM `tabPacking Slip`
|
||||
WHERE delivery_note = %(delivery_note)s AND docstatus = 1 AND
|
||||
((from_case_no BETWEEN %(from_case_no)s AND %(to_case_no)s)
|
||||
|
||||
@@ -724,7 +724,7 @@ def get_serial_no_details(item_code, warehouse, stock_qty, serial_no):
|
||||
return {'serial_no': serial_no}
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_bin_details_and_serial_nos(item_code, warehouse, has_batch_no, stock_qty=None, serial_no=None):
|
||||
def get_bin_details_and_serial_nos(item_code, warehouse, has_batch_no=None, stock_qty=None, serial_no=None):
|
||||
bin_details_and_serial_nos = {}
|
||||
bin_details_and_serial_nos.update(get_bin_details(item_code, warehouse))
|
||||
if flt(stock_qty) > 0:
|
||||
|
||||
@@ -15,8 +15,8 @@ def execute(filters=None):
|
||||
|
||||
def get_columns():
|
||||
columns = [
|
||||
_("Company") + ":Link/Item:250",
|
||||
_("Warehouse") + ":Link/Item:150",
|
||||
_("Company") + ":Link/Company:250",
|
||||
_("Warehouse") + ":Link/Warehouse:150",
|
||||
_("Item") + ":Link/Item:150",
|
||||
_("Description") + "::300",
|
||||
_("Current Qty") + ":Float:100",
|
||||
@@ -31,7 +31,7 @@ def get_total_stock(filters):
|
||||
if filters.get("group_by") == "Warehouse":
|
||||
if filters.get("company"):
|
||||
conditions += " AND warehouse.company = '%s'" % frappe.db.escape(filters.get("company"), percent=False)
|
||||
|
||||
|
||||
conditions += " GROUP BY ledger.warehouse, item.item_code"
|
||||
columns += "'' as company, ledger.warehouse"
|
||||
else:
|
||||
|
||||
@@ -15,7 +15,7 @@ def get_stock_value_from_bin(warehouse=None, item_code=None):
|
||||
values = {}
|
||||
conditions = ""
|
||||
if warehouse:
|
||||
conditions += """ and warehouse in (
|
||||
conditions += """ and `tabBin`.warehouse in (
|
||||
select w2.name from `tabWarehouse` w1
|
||||
join `tabWarehouse` w2 on
|
||||
w1.name = %(warehouse)s
|
||||
@@ -25,11 +25,12 @@ def get_stock_value_from_bin(warehouse=None, item_code=None):
|
||||
values['warehouse'] = warehouse
|
||||
|
||||
if item_code:
|
||||
conditions += " and item_code = %(item_code)s"
|
||||
conditions += " and `tabBin`.item_code = %(item_code)s"
|
||||
|
||||
values['item_code'] = item_code
|
||||
|
||||
query = "select sum(stock_value) from `tabBin` where 1 = 1 %s" % conditions
|
||||
query = """select sum(stock_value) from `tabBin`, `tabItem` where 1 = 1
|
||||
and `tabItem`.name = `tabBin`.item_code and ifnull(`tabItem`.disabled, 0) = 0 %s""" % conditions
|
||||
|
||||
stock_value = frappe.db.sql(query, values)
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -87,6 +87,7 @@ class Issue(Document):
|
||||
from copy import deepcopy
|
||||
replicated_issue = deepcopy(self)
|
||||
replicated_issue.subject = subject
|
||||
replicated_issue.issue_split_from = self.name
|
||||
frappe.get_doc(replicated_issue).insert()
|
||||
# Replicate linked Communications
|
||||
# todo get all communications in timeline before this, and modify them to append them to new doc
|
||||
@@ -96,6 +97,15 @@ class Issue(Document):
|
||||
doc = frappe.get_doc("Communication", communication.name)
|
||||
doc.reference_name = replicated_issue.name
|
||||
doc.save(ignore_permissions=True)
|
||||
|
||||
frappe.get_doc({
|
||||
"doctype": "Comment",
|
||||
"comment_type": "Info",
|
||||
"reference_doctype": "Issue",
|
||||
"reference_name": replicated_issue.name,
|
||||
"content": " - Split the Issue from <a href='#Form/Issue/{0}'>{1}</a>".format(self.name, frappe.bold(self.name))
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
return replicated_issue.name
|
||||
|
||||
def get_list_context(context=None):
|
||||
@@ -177,4 +187,4 @@ def make_issue_from_communication(communication, ignore_communication_links=Fals
|
||||
|
||||
link_communication_to_document(doc, "Issue", issue.name, ignore_communication_links)
|
||||
|
||||
return issue.name
|
||||
return issue.name
|
||||
|
||||
@@ -51,14 +51,14 @@ erpnext.SupportAnalytics = frappe.views.GridReportWithPlot.extend({
|
||||
// add Opening, Closing, Totals rows
|
||||
// if filtered by account and / or voucher
|
||||
var me = this;
|
||||
var total_tickets = {name:"All Tickets", "id": "all-tickets",
|
||||
var total_tickets = {name:__("All Tickets"), "id": "all-tickets",
|
||||
checked:true};
|
||||
var days_to_close = {name:"Days to Close", "id":"days-to-close",
|
||||
var days_to_close = {name:__("Days to Close"), "id":"days-to-close",
|
||||
checked:false};
|
||||
var total_closed = {};
|
||||
var hours_to_close = {name:"Hours to Close", "id":"hours-to-close",
|
||||
var hours_to_close = {name:__("Hours to Close"), "id":"hours-to-close",
|
||||
checked:false};
|
||||
var hours_to_respond = {name:"Hours to Respond", "id":"hours-to-respond",
|
||||
var hours_to_respond = {name:__("Hours to Respond"), "id":"hours-to-respond",
|
||||
checked:false};
|
||||
var total_responded = {};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user