Skip to content

Commit

Permalink
Merge branch 'version-13-hotfix' into patch-4
Browse files Browse the repository at this point in the history
  • Loading branch information
ankush authored Mar 28, 2022
2 parents 3a5f5d5 + 471a327 commit fc5fd34
Show file tree
Hide file tree
Showing 160 changed files with 2,920 additions and 1,050 deletions.
6 changes: 0 additions & 6 deletions .github/workflows/patch.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ on:
paths-ignore:
- '**.js'
- '**.md'
types: [opened, unlabeled, synchronize, reopened]
workflow_dispatch:


Expand All @@ -30,11 +29,6 @@ jobs:
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3

steps:
- name: Check for merge conficts label
if: ${{ contains(github.event.pull_request.labels.*.name, 'conflicts') }}
run: |
echo "Remove merge conflicts and remove conflict label to run CI"
exit 1
- name: Clone
uses: actions/checkout@v2

Expand Down
7 changes: 0 additions & 7 deletions .github/workflows/server-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ on:
paths-ignore:
- '**.js'
- '**.md'
types: [opened, unlabeled, synchronize, reopened]
workflow_dispatch:
push:
branches: [ develop ]
Expand Down Expand Up @@ -40,12 +39,6 @@ jobs:
options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3

steps:
- name: Check for merge conficts label
if: ${{ contains(github.event.pull_request.labels.*.name, 'conflicts') }}
run: |
echo "Remove merge conflicts and remove conflict label to run CI"
exit 1
- name: Clone
uses: actions/checkout@v2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ def reconcile_vouchers(bank_transaction_name, vouchers):
}), transaction.currency, company_account)

if total_amount > transaction.unallocated_amount:
frappe.throw(_("The Sum Total of Amounts of All Selected Vouchers Should be Less than the Unallocated Amount of the Bank Transaction"))
frappe.throw(_("The sum total of amounts of all selected vouchers should be less than the unallocated amount of the bank transaction"))
account = frappe.db.get_value("Bank Account", transaction.bank_account, "account")

for voucher in vouchers:
Expand Down
9 changes: 7 additions & 2 deletions erpnext/accounts/doctype/bank_transaction/bank_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,13 @@ def get_paid_amount(payment_entry, currency, bank_account):
paid_amount_field = "paid_amount"
if payment_entry.payment_document == 'Payment Entry':
doc = frappe.get_doc("Payment Entry", payment_entry.payment_entry)
paid_amount_field = ("base_paid_amount"
if doc.paid_to_account_currency == currency else "paid_amount")

if doc.payment_type == 'Receive':
paid_amount_field = ("received_amount"
if doc.paid_to_account_currency == currency else "base_received_amount")
elif doc.payment_type == 'Pay':
paid_amount_field = ("paid_amount"
if doc.paid_to_account_currency == currency else "base_paid_amount")

return frappe.db.get_value(payment_entry.payment_document,
payment_entry.payment_entry, paid_amount_field)
Expand Down
4 changes: 3 additions & 1 deletion erpnext/accounts/doctype/gl_entry/gl_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ def autoname(self):
name will be changed using autoname options (in a scheduled job)
"""
self.name = frappe.generate_hash(txt="", length=10)
if self.meta.autoname == "hash":
self.to_rename = 0

def validate(self):
self.flags.ignore_submit_comment = True
Expand Down Expand Up @@ -135,7 +137,7 @@ def validate_allowed_dimensions(self):

def check_pl_account(self):
if self.is_opening=='Yes' and \
frappe.db.get_value("Account", self.account, "report_type")=="Profit and Loss":
frappe.db.get_value("Account", self.account, "report_type")=="Profit and Loss" and not self.is_cancelled:
frappe.throw(_("{0} {1}: 'Profit and Loss' type account {2} not allowed in Opening Entry")
.format(self.voucher_type, self.voucher_no, self.account))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# See license.txt

import frappe
from frappe.tests.utils import FrappeTestCase

from erpnext.accounts.doctype.accounting_dimension.test_accounting_dimension import (
create_dimension,
Expand All @@ -10,11 +11,10 @@
from erpnext.accounts.doctype.opening_invoice_creation_tool.opening_invoice_creation_tool import (
get_temporary_opening_account,
)
from erpnext.tests.utils import ERPNextTestCase

test_dependencies = ["Customer", "Supplier", "Accounting Dimension"]

class TestOpeningInvoiceCreationTool(ERPNextTestCase):
class TestOpeningInvoiceCreationTool(FrappeTestCase):
@classmethod
def setUpClass(self):
if not frappe.db.exists("Company", "_Test Opening Invoice Company"):
Expand Down
7 changes: 5 additions & 2 deletions erpnext/accounts/doctype/payment_request/payment_request.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,8 +376,8 @@ def make_payment_request(**args):
if args.order_type == "Shopping Cart" or args.mute_email:
pr.flags.mute_email = True

pr.insert(ignore_permissions=True)
if args.submit_doc:
pr.insert(ignore_permissions=True)
pr.submit()

if args.order_type == "Shopping Cart":
Expand All @@ -394,7 +394,10 @@ def get_amount(ref_doc, payment_account=None):
"""get amount based on doctype"""
dt = ref_doc.doctype
if dt in ["Sales Order", "Purchase Order"]:
grand_total = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid)
if ref_doc.party_account_currency == ref_doc.currency:
grand_total = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid)
else:
grand_total = flt(ref_doc.grand_total) - flt(ref_doc.advance_paid) / ref_doc.conversion_rate

elif dt in ["Sales Invoice", "Purchase Invoice"]:
if ref_doc.party_account_currency == ref_doc.currency:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ def test_multiple_payment_entries_against_sales_order(self):
pr1 = make_payment_request(dt="Sales Order", dn=so.name,
recipient_id="nabin@erpnext.com", return_doc=1)
pr1.grand_total = 200
pr1.insert()
pr1.submit()

# Make a 2nd Payment Request
Expand Down
5 changes: 3 additions & 2 deletions erpnext/accounts/doctype/pos_invoice/pos_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def validate(self):

def on_submit(self):
# create the loyalty point ledger entry if the customer is enrolled in any loyalty program
if self.loyalty_program:
if not self.is_return and self.loyalty_program:
self.make_loyalty_point_entry()
elif self.is_return and self.return_against and self.loyalty_program:
against_psi_doc = frappe.get_doc("POS Invoice", self.return_against)
Expand Down Expand Up @@ -88,7 +88,7 @@ def before_cancel(self):
def on_cancel(self):
# run on cancel method of selling controller
super(SalesInvoice, self).on_cancel()
if self.loyalty_program:
if not self.is_return and self.loyalty_program:
self.delete_loyalty_point_entry()
elif self.is_return and self.return_against and self.loyalty_program:
against_psi_doc = frappe.get_doc("POS Invoice", self.return_against)
Expand Down Expand Up @@ -456,6 +456,7 @@ def create_payment_request(self):
pay_req = self.get_existing_payment_request(pay)
if not pay_req:
pay_req = self.get_new_payment_request(pay)
pay_req.insert()
pay_req.submit()
else:
pay_req.request_phone_payment()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,10 @@ def test_consolidated_credit_note_creation(self):
pos_inv_cn = make_sales_return(pos_inv.name)
pos_inv_cn.set("payments", [])
pos_inv_cn.append('payments', {
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': -300
'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': -100
})
pos_inv_cn.append('payments', {
'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': -200
})
pos_inv_cn.paid_amount = -300
pos_inv_cn.submit()
Expand All @@ -98,7 +101,12 @@ def test_consolidated_credit_note_creation(self):

pos_inv_cn.load_from_db()
self.assertTrue(frappe.db.exists("Sales Invoice", pos_inv_cn.consolidated_invoice))
self.assertTrue(frappe.db.get_value("Sales Invoice", pos_inv_cn.consolidated_invoice, "is_return"))
consolidated_credit_note = frappe.get_doc("Sales Invoice", pos_inv_cn.consolidated_invoice)
self.assertEqual(consolidated_credit_note.is_return, 1)
self.assertEqual(consolidated_credit_note.payments[0].mode_of_payment, 'Cash')
self.assertEqual(consolidated_credit_note.payments[0].amount, -100)
self.assertEqual(consolidated_credit_note.payments[1].mode_of_payment, 'Bank Draft')
self.assertEqual(consolidated_credit_note.payments[1].amount, -200)

finally:
frappe.set_user("Administrator")
Expand Down
6 changes: 6 additions & 0 deletions erpnext/accounts/doctype/purchase_invoice/purchase_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
from erpnext.assets.doctype.asset.asset import get_asset_account, is_cwip_accounting_enabled
from erpnext.assets.doctype.asset_category.asset_category import get_asset_category_account
from erpnext.buying.utils import check_on_hold_or_closed_status
from erpnext.controllers.accounts_controller import validate_account_head
from erpnext.controllers.buying_controller import BuyingController
from erpnext.stock import get_warehouse_account_map
from erpnext.stock.doctype.purchase_receipt.purchase_receipt import (
Expand Down Expand Up @@ -105,6 +106,7 @@ def validate(self):
self.validate_uom_is_integer("uom", "qty")
self.validate_uom_is_integer("stock_uom", "stock_qty")
self.set_expense_account(for_validate=True)
self.validate_expense_account()
self.set_against_expense_account()
self.validate_write_off_account()
self.validate_multiple_billing("Purchase Receipt", "pr_detail", "amount", "items")
Expand Down Expand Up @@ -309,6 +311,10 @@ def set_expense_account(self, for_validate=False):
elif not item.expense_account and for_validate:
throw(_("Expense account is mandatory for item {0}").format(item.item_code or item.item_name))

def validate_expense_account(self):
for item in self.get('items'):
validate_account_head(item.idx, item.expense_account, self.company, 'Expense')

def set_against_expense_account(self):
against_accounts = []
for item in self.get("items"):
Expand Down
45 changes: 31 additions & 14 deletions erpnext/accounts/doctype/sales_invoice/sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,18 @@
get_gl_entries_on_asset_regain,
make_depreciation_entry,
)
from erpnext.controllers.accounts_controller import validate_account_head
from erpnext.controllers.selling_controller import SellingController
from erpnext.healthcare.utils import manage_invoice_submit_cancel
from erpnext.projects.doctype.timesheet.timesheet import get_projectwise_timesheet_data
from erpnext.setup.doctype.company.company import update_company_current_month_sales
from erpnext.stock.doctype.batch.batch import set_batch_nos
from erpnext.stock.doctype.delivery_note.delivery_note import update_billed_amount_based_on_so
from erpnext.stock.doctype.serial_no.serial_no import get_delivery_note_serial_no, get_serial_nos
from erpnext.stock.utils import calculate_mapped_packed_items_return
from erpnext.stock.doctype.serial_no.serial_no import (
get_delivery_note_serial_no,
get_serial_nos,
update_serial_nos_after_submit,
)

form_grid_templates = {
"items": "templates/form_grid/item_grid.html"
Expand Down Expand Up @@ -110,6 +114,8 @@ def validate(self):
self.validate_fixed_asset()
self.set_income_account_for_fixed_assets()
self.validate_item_cost_centers()
self.validate_income_account()

validate_inter_company_party(self.doctype, self.customer, self.company, self.inter_company_invoice_reference)

if cint(self.is_pos):
Expand Down Expand Up @@ -177,6 +183,10 @@ def validate_item_cost_centers(self):
if cost_center_company != self.company:
frappe.throw(_("Row #{0}: Cost Center {1} does not belong to company {2}").format(frappe.bold(item.idx), frappe.bold(item.cost_center), frappe.bold(self.company)))

def validate_income_account(self):
for item in self.get('items'):
validate_account_head(item.idx, item.income_account, self.company, 'Income')

def set_tax_withholding(self):
tax_withholding_details = get_party_tax_withholding_details(self)

Expand Down Expand Up @@ -228,6 +238,9 @@ def on_submit(self):
# because updating reserved qty in bin depends upon updated delivered qty in SO
if self.update_stock == 1:
self.update_stock_ledger()
if self.is_return and self.update_stock:
update_serial_nos_after_submit(self, "items")


# this sequence because outstanding may get -ve
self.make_gl_entries()
Expand Down Expand Up @@ -752,11 +765,8 @@ def update_current_stock(self):

def update_packing_list(self):
if cint(self.update_stock) == 1:
if cint(self.is_return) and self.return_against:
calculate_mapped_packed_items_return(self)
else:
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
make_packing_list(self)
from erpnext.stock.doctype.packed_item.packed_item import make_packing_list
make_packing_list(self)
else:
self.set('packed_items', [])

Expand Down Expand Up @@ -1415,12 +1425,19 @@ def set_loyalty_program_tier(self):
frappe.db.set_value("Customer", self.customer, "loyalty_program_tier", lp_details.tier_name)

def get_returned_amount(self):
returned_amount = frappe.db.sql("""
select sum(grand_total)
from `tabSales Invoice`
where docstatus=1 and is_return=1 and ifnull(return_against, '')=%s
""", self.name)
return abs(flt(returned_amount[0][0])) if returned_amount else 0
from frappe.query_builder.functions import Coalesce, Sum
doc = frappe.qb.DocType(self.doctype)
returned_amount = (
frappe.qb.from_(doc)
.select(Sum(doc.grand_total))
.where(
(doc.docstatus == 1)
& (doc.is_return == 1)
& (Coalesce(doc.return_against, '') == self.name)
)
).run()

return abs(returned_amount[0][0]) if returned_amount[0][0] else 0

# redeem the loyalty points.
def apply_loyalty_points(self):
Expand Down Expand Up @@ -1700,7 +1717,6 @@ def make_maintenance_schedule(source_name, target_doc=None):
@frappe.whitelist()
def make_delivery_note(source_name, target_doc=None):
def set_missing_values(source, target):
target.ignore_pricing_rule = 1
target.run_method("set_missing_values")
target.run_method("set_po_nos")
target.run_method("calculate_taxes_and_totals")
Expand Down Expand Up @@ -1745,6 +1761,7 @@ def update_item(source_doc, target_doc, source_parent):
}
}, target_doc, set_missing_values)

doclist.set_onload('ignore_price_list', True)
return doclist

@frappe.whitelist()
Expand Down
35 changes: 33 additions & 2 deletions erpnext/accounts/doctype/sales_invoice/test_sales_invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -812,12 +812,37 @@ def test_pos_change_amount(self):
pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 50})
pos.append("payments", {'mode_of_payment': 'Cash', 'account': 'Cash - TCP1', 'amount': 60})

pos.change_amount = 5.0
pos.write_off_outstanding_amount_automatically = 1
pos.insert()
pos.submit()

self.assertEqual(pos.grand_total, 100.0)
self.assertEqual(pos.write_off_amount, -5)
self.assertEqual(pos.write_off_amount, 0)

def test_auto_write_off_amount(self):
make_pos_profile(company="_Test Company with perpetual inventory", income_account = "Sales - TCP1",
expense_account = "Cost of Goods Sold - TCP1", warehouse="Stores - TCP1", cost_center = "Main - TCP1", write_off_account="_Test Write Off - TCP1")

make_purchase_receipt(company= "_Test Company with perpetual inventory",
item_code= "_Test FG Item",warehouse= "Stores - TCP1", cost_center= "Main - TCP1")

pos = create_sales_invoice(company= "_Test Company with perpetual inventory",
debit_to="Debtors - TCP1", item_code= "_Test FG Item", warehouse="Stores - TCP1",
income_account = "Sales - TCP1", expense_account = "Cost of Goods Sold - TCP1",
cost_center = "Main - TCP1", do_not_save=True)

pos.is_pos = 1
pos.update_stock = 1

pos.append("payments", {'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - TCP1', 'amount': 50})
pos.append("payments", {'mode_of_payment': 'Cash', 'account': 'Cash - TCP1', 'amount': 40})

pos.write_off_outstanding_amount_automatically = 1
pos.insert()
pos.submit()

self.assertEqual(pos.grand_total, 100.0)
self.assertEqual(pos.write_off_amount, 10)

def test_pos_with_no_gl_entry_for_change_amount(self):
frappe.db.set_value('Accounts Settings', None, 'post_change_gl_entries', 0)
Expand Down Expand Up @@ -2540,6 +2565,12 @@ def test_multi_currency_deferred_revenue_via_journal_entry(self):

frappe.db.set_value('Accounts Settings', None, 'acc_frozen_upto', None)

def test_standalone_serial_no_return(self):
si = create_sales_invoice(item_code="_Test Serialized Item With Series", update_stock=True, is_return=True, qty=-1)
si.reload()
self.assertTrue(si.items[0].serial_no)


def get_sales_invoice_for_e_invoice():
si = make_sales_invoice_for_ewaybill()
si.naming_series = 'INV-2020-.#####'
Expand Down
3 changes: 1 addition & 2 deletions erpnext/accounts/doctype/shipping_rule/shipping_rule.py
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,7 @@ def apply(self, doc):
if doc.currency != doc.company_currency:
shipping_amount = flt(shipping_amount / doc.conversion_rate, 2)

if shipping_amount:
self.add_shipping_rule_to_tax_table(doc, shipping_amount)
self.add_shipping_rule_to_tax_table(doc, shipping_amount)

def get_shipping_amount_from_rules(self, value):
for condition in self.get("conditions"):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ def get_loan_amount(filters):

total_amount += flt(amount)

return amount
return total_amount

def get_balance_row(label, amount, account_currency):
if amount > 0:
Expand Down
Loading

0 comments on commit fc5fd34

Please sign in to comment.