Merge branch 'develop' into revert-drop-einvoicing
This commit is contained in:
commit
2c100a5313
1
.flake8
1
.flake8
@ -28,6 +28,7 @@ ignore =
|
||||
B007,
|
||||
B950,
|
||||
W191,
|
||||
E124, # closing bracket, irritating while writing QB code
|
||||
|
||||
max-line-length = 200
|
||||
exclude=.github/helper/semgrep_rules
|
||||
|
@ -2,9 +2,10 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from functools import reduce
|
||||
|
||||
import frappe
|
||||
from frappe.utils import flt
|
||||
from six.moves import reduce
|
||||
|
||||
from erpnext.controllers.status_updater import StatusUpdater
|
||||
|
||||
|
@ -5,7 +5,6 @@
|
||||
import frappe
|
||||
from frappe import _, scrub
|
||||
from frappe.utils import cint, flt
|
||||
from six import iteritems
|
||||
|
||||
from erpnext.accounts.party import get_partywise_advanced_payment_amount
|
||||
from erpnext.accounts.report.accounts_receivable.accounts_receivable import ReceivablePayableReport
|
||||
@ -40,7 +39,7 @@ class AccountsReceivableSummary(ReceivablePayableReport):
|
||||
if self.filters.show_gl_balance:
|
||||
gl_balance_map = get_gl_balance(self.filters.report_date)
|
||||
|
||||
for party, party_dict in iteritems(self.party_total):
|
||||
for party, party_dict in self.party_total.items():
|
||||
if party_dict.outstanding == 0:
|
||||
continue
|
||||
|
||||
|
@ -2,13 +2,14 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from urllib.parse import urlencode
|
||||
|
||||
import frappe
|
||||
import requests
|
||||
from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import get_url_to_form
|
||||
from frappe.utils.file_manager import get_file_path
|
||||
from six.moves.urllib.parse import urlencode
|
||||
|
||||
|
||||
class LinkedInSettings(Document):
|
||||
|
@ -5,11 +5,11 @@
|
||||
import csv
|
||||
import math
|
||||
import time
|
||||
from io import StringIO
|
||||
|
||||
import dateutil
|
||||
import frappe
|
||||
from frappe import _
|
||||
from six import StringIO
|
||||
|
||||
import erpnext.erpnext_integrations.doctype.amazon_mws_settings.amazon_mws_api as mws
|
||||
|
||||
|
@ -2,13 +2,14 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from urllib.parse import urlencode
|
||||
|
||||
import frappe
|
||||
import gocardless_pro
|
||||
from frappe import _
|
||||
from frappe.integrations.utils import create_payment_gateway, create_request_log
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import call_hook_method, cint, flt, get_url
|
||||
from six.moves.urllib.parse import urlencode
|
||||
|
||||
|
||||
class GoCardlessSettings(Document):
|
||||
|
@ -2,12 +2,13 @@
|
||||
# For license information, please see license.txt
|
||||
|
||||
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.custom.doctype.custom_field.custom_field import create_custom_field
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils.nestedset import get_root_of
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
|
||||
class WoocommerceSettings(Document):
|
||||
|
@ -1,10 +1,10 @@
|
||||
import base64
|
||||
import hashlib
|
||||
import hmac
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
from six.moves.urllib.parse import urlparse
|
||||
|
||||
from erpnext import get_default_company
|
||||
|
||||
|
@ -149,6 +149,7 @@ class BOM(WebsiteGenerator):
|
||||
self.set_bom_material_details()
|
||||
self.set_bom_scrap_items_detail()
|
||||
self.validate_materials()
|
||||
self.validate_transfer_against()
|
||||
self.set_routing_operations()
|
||||
self.validate_operations()
|
||||
self.calculate_cost()
|
||||
@ -690,6 +691,12 @@ class BOM(WebsiteGenerator):
|
||||
if act_pbom and act_pbom[0][0]:
|
||||
frappe.throw(_("Cannot deactivate or cancel BOM as it is linked with other BOMs"))
|
||||
|
||||
def validate_transfer_against(self):
|
||||
if not self.with_operations:
|
||||
self.transfer_material_against = "Work Order"
|
||||
if not self.transfer_material_against and not self.is_new():
|
||||
frappe.throw(_("Setting {} is required").format(self.meta.get_label("transfer_material_against")), title=_("Missing value"))
|
||||
|
||||
def set_routing_operations(self):
|
||||
if self.routing and self.with_operations and not self.operations:
|
||||
self.get_routing()
|
||||
|
@ -403,6 +403,36 @@ class TestBOM(ERPNextTestCase):
|
||||
|
||||
new_bom.delete()
|
||||
|
||||
def test_valid_transfer_defaults(self):
|
||||
bom_with_op = frappe.db.get_value("BOM", {"item": "_Test FG Item 2", "with_operations": 1, "is_active": 1})
|
||||
bom = frappe.copy_doc(frappe.get_doc("BOM", bom_with_op), ignore_no_copy=False)
|
||||
|
||||
# test defaults
|
||||
bom.docstatus = 0
|
||||
bom.transfer_material_against = None
|
||||
bom.insert()
|
||||
self.assertEqual(bom.transfer_material_against, "Work Order")
|
||||
|
||||
bom.reload()
|
||||
bom.transfer_material_against = None
|
||||
with self.assertRaises(frappe.ValidationError):
|
||||
bom.save()
|
||||
bom.reload()
|
||||
|
||||
# test saner default
|
||||
bom.transfer_material_against = "Job Card"
|
||||
bom.with_operations = 0
|
||||
bom.save()
|
||||
self.assertEqual(bom.transfer_material_against, "Work Order")
|
||||
|
||||
# test no value on existing doc
|
||||
bom.transfer_material_against = None
|
||||
bom.with_operations = 0
|
||||
bom.save()
|
||||
self.assertEqual(bom.transfer_material_against, "Work Order")
|
||||
bom.delete()
|
||||
|
||||
|
||||
def get_default_bom(item_code="_Test FG Item 2"):
|
||||
return frappe.db.get_value("BOM", {"item": item_code, "is_active": 1, "is_default": 1})
|
||||
|
||||
|
@ -65,6 +65,7 @@ class WorkOrder(Document):
|
||||
self.validate_warehouse_belongs_to_company()
|
||||
self.calculate_operating_cost()
|
||||
self.validate_qty()
|
||||
self.validate_transfer_against()
|
||||
self.validate_operation_time()
|
||||
self.status = self.get_status()
|
||||
|
||||
@ -72,6 +73,7 @@ class WorkOrder(Document):
|
||||
|
||||
self.set_required_items(reset_only_qty = len(self.get("required_items")))
|
||||
|
||||
|
||||
def validate_sales_order(self):
|
||||
if self.sales_order:
|
||||
self.check_sales_order_on_hold_or_close()
|
||||
@ -625,6 +627,16 @@ class WorkOrder(Document):
|
||||
if not self.qty > 0:
|
||||
frappe.throw(_("Quantity to Manufacture must be greater than 0."))
|
||||
|
||||
def validate_transfer_against(self):
|
||||
if not self.docstatus == 1:
|
||||
# let user configure operations until they're ready to submit
|
||||
return
|
||||
if not self.operations:
|
||||
self.transfer_material_against = "Work Order"
|
||||
if not self.transfer_material_against:
|
||||
frappe.throw(_("Setting {} is required").format(self.meta.get_label("transfer_material_against")), title=_("Missing value"))
|
||||
|
||||
|
||||
def validate_operation_time(self):
|
||||
for d in self.operations:
|
||||
if not d.time_in_mins > 0:
|
||||
|
@ -340,4 +340,5 @@ erpnext.patches.v14_0.delete_hospitality_doctypes # 20-01-2022
|
||||
erpnext.patches.v14_0.delete_agriculture_doctypes
|
||||
erpnext.patches.v14_0.rearrange_company_fields
|
||||
erpnext.patches.v14_0.update_leave_notification_template
|
||||
erpnext.patches.v14_0.restore_einvoice_fields
|
||||
erpnext.patches.v14_0.restore_einvoice_fields
|
||||
erpnext.patches.v13_0.update_sane_transfer_against
|
||||
|
11
erpnext/patches/v13_0/update_sane_transfer_against.py
Normal file
11
erpnext/patches/v13_0/update_sane_transfer_against.py
Normal file
@ -0,0 +1,11 @@
|
||||
import frappe
|
||||
|
||||
|
||||
def execute():
|
||||
bom = frappe.qb.DocType("BOM")
|
||||
|
||||
(frappe.qb
|
||||
.update(bom)
|
||||
.set(bom.transfer_material_against, "Work Order")
|
||||
.where(bom.with_operations == 0)
|
||||
).run()
|
@ -1,11 +1,11 @@
|
||||
import datetime
|
||||
import zipfile
|
||||
from csv import QUOTE_NONNUMERIC
|
||||
from io import BytesIO
|
||||
|
||||
import frappe
|
||||
import pandas as pd
|
||||
from frappe import _
|
||||
from six import BytesIO
|
||||
|
||||
from .datev_constants import DataCategory
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
import zipfile
|
||||
from io import BytesIO
|
||||
from unittest import TestCase
|
||||
|
||||
import frappe
|
||||
from frappe.utils import cstr, now_datetime, today
|
||||
from six import BytesIO
|
||||
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.regional.germany.utils.datev.datev_constants import (
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
|
||||
import copy
|
||||
from urllib.parse import quote
|
||||
|
||||
import frappe
|
||||
from frappe import _
|
||||
@ -10,7 +11,6 @@ from frappe.utils import cint, cstr, nowdate
|
||||
from frappe.utils.nestedset import NestedSet
|
||||
from frappe.website.utils import clear_cache
|
||||
from frappe.website.website_generator import WebsiteGenerator
|
||||
from six.moves.urllib.parse import quote
|
||||
|
||||
from erpnext.shopping_cart.filters import ProductFiltersBuilder
|
||||
from erpnext.shopping_cart.product_info import set_product_info_for_website
|
||||
|
@ -86,10 +86,10 @@ frappe.query_reports["Stock Ledger"] = {
|
||||
],
|
||||
"formatter": function (value, row, column, data, default_formatter) {
|
||||
value = default_formatter(value, row, column, data);
|
||||
if (column.fieldname == "out_qty" && data.out_qty < 0) {
|
||||
if (column.fieldname == "out_qty" && data && data.out_qty < 0) {
|
||||
value = "<span style='color:red'>" + value + "</span>";
|
||||
}
|
||||
else if (column.fieldname == "in_qty" && data.in_qty > 0) {
|
||||
else if (column.fieldname == "in_qty" && data && data.in_qty > 0) {
|
||||
value = "<span style='color:green'>" + value + "</span>";
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user