Пример #1
0
    def raise_exceptions(self):
        deficiency = min(e["diff"] for e in self.exceptions)

        if (
            self.exceptions[0]["voucher_type"],
            self.exceptions[0]["voucher_no"],
        ) in frappe.local.flags.currently_saving:

            msg = _("{0} units of {1} needed in {2} to complete this transaction.").format(
                abs(deficiency),
                frappe.get_desk_link("Item", self.item_code),
                frappe.get_desk_link("Warehouse", self.warehouse),
            )
        else:
            msg = _("{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction.").format(
                abs(deficiency),
                frappe.get_desk_link("Item", self.item_code),
                frappe.get_desk_link("Warehouse", self.warehouse),
                self.exceptions[0]["posting_date"],
                self.exceptions[0]["posting_time"],
                frappe.get_desk_link(self.exceptions[0]["voucher_type"], self.exceptions[0]["voucher_no"]),
            )

        if self.verbose:
            frappe.throw(msg, NegativeStockError, title="Insufficent Stock")
        else:
            raise NegativeStockError, msg
Пример #2
0
def validate(doc,method):
	ship_pincode = frappe.db.get_value("Address", doc.shipping_address_name ,"pincode")
	bill_pincode = frappe.db.get_value("Address", doc.customer_address ,"pincode")
	ship_gstin = frappe.db.get_value("Address", doc.shipping_address_name ,"gstin")
	bill_gstin = frappe.db.get_value("Address", doc.customer_address ,"gstin")
	bill_state = frappe.db.get_value("Address", doc.customer_address, "state_rigpl")
	ship_country = frappe.db.get_value("Address", doc.shipping_address_name, "country")
	template_doc = frappe.get_doc("Sales Taxes and Charges Template", doc.taxes_and_charges)

	if ship_pincode is None:
		frappe.throw(("Shipping Pincode is Mandatory or NA, please correct it in Shipping Address {0}").\
			format(frappe.get_desk_link('Address', doc.shipping_address_name)))

	if bill_pincode is None:
		frappe.throw(("Billing Pincode is Mandatory or NA, please correct it in Billing Address {0}").\
			format(frappe.get_desk_link('Address', doc.shipping_address_name)))

	doc.shipping_address_gstin = ship_gstin
	doc.billing_address_gstin = bill_gstin
	
	for items in doc.items:
		custom_tariff = frappe.db.get_value("Item", items.item_code, "customs_tariff_number")
		if custom_tariff:
			if len(custom_tariff) == 8:
				items.gst_hsn_code = custom_tariff 
			else:
				frappe.throw(("Item Code {0} in line# {1} has a Custom Tariff {2} which not  \
					8 digit, please get the Custom Tariff corrected").\
					format(items.item_code, items.idx, custom_tariff))
		else:
			frappe.throw(("Item Code {0} in line# {1} does not have linked Customs \
				Tariff in Item Master").format(items.item_code, items.idx))
	
	#Check if Shipping State is Same as Template State then check if the tax template is LOCAL
	#Else if the States are different then the template should NOT BE LOCAL
	if bill_state == template_doc.state and template_doc.is_export == 0:
		if template_doc.is_local_sales != 1:
			frappe.throw(("Selected Tax {0} is NOT LOCAL Tax but Billing Address is \
				in Same State {1}, hence either change Billing Address or Change the \
				Selected Tax").format(doc.taxes_and_charges, bill_state))
	elif ship_country == 'India' and bill_state != template_doc.state:
		if template_doc.is_local_sales == 1:
			frappe.throw(("Selected Tax {0} is LOCAL Tax but Billing Address is \
				in Different State {1}, hence either change Billing Address or Change the \
				Selected Tax").format(doc.taxes_and_charges, bill_state))
	elif ship_country != 'India': #Case of EXPORTS
		if template_doc.is_export != 1:
			frappe.throw(("Selected Tax {0} is for Indian Sales but Billing Address is \
				in Different Country {1}, hence either change Billing Address or Change the \
				Selected Tax").format(doc.taxes_and_charges, ship_country))
	#lastly check the child taxes table are in sync with the template
	check_taxes_integrity(doc, method, template_doc)
Пример #3
0
def create_new_carrier_track(doc, method):
    # If SI is from Cancelled Doc then update the Existing Carrier Track
    is_tracked = is_tracked_transporter(doc, method)
    if is_tracked == 1:
        if doc.amended_from:
            existing_track = check_existing_track(doc.doctype, doc.amended_from)
            if existing_track:
                exist_track = frappe.get_doc("Carrier Tracking", existing_track[0][0])
                if exist_track.docstatus == 0:
                    doc.lr_no = exist_track.awb_number
                    exist_track.receiver_name = doc.customer
                    exist_track.document_name = doc.name
                    doc.transporters = exist_track.carrier_name
                    exist_track.flags.ignore_permissions = True
                    exist_track.save()
                    frappe.msgprint(("Updated {0}").format(frappe.get_desk_link('Carrier Tracking', exist_track.name)))
                elif exist_track.docstatus == 1:
                    route = doc.name.lower() + exist_track.name.lower()
                    frappe.db.set_value("Carrier Tracking", exist_track.name, "published", 1)
                    frappe.db.set_value("Carrier Tracking", exist_track.name, "document_name", doc.name)
                    frappe.db.set_value("Carrier Tracking", exist_track.name, "reference_document_name", "")
                    frappe.db.set_value("Carrier Tracking", exist_track.name, "route", route)
                else:
                    new_ctrack = frappe.copy_doc(exist_track)
                    new_ctrack.amended_from = exist_track.name
                    new_ctrack.document_name = doc.name
                    new_ctrack.insert(ignore_permissions=True)
                    frappe.msgprint(("Added New {0}").format(frappe.get_desk_link \
                                                                 ('Carrier Tracking', new_ctrack.name)))
            else:
                create_new_ship_track(doc)

        elif check_existing_track(doc.doctype, doc.name) is None:
            # Dont create a new Tracker if already exists
            create_new_ship_track(doc)
Пример #4
0
def get_available_item_locations(item_code,
                                 from_warehouses,
                                 required_qty,
                                 company,
                                 ignore_validation=False):
    locations = []
    has_serial_no = frappe.get_cached_value("Item", item_code, "has_serial_no")
    has_batch_no = frappe.get_cached_value("Item", item_code, "has_batch_no")

    if has_batch_no and has_serial_no:
        locations = get_available_item_locations_for_serial_and_batched_item(
            item_code, from_warehouses, required_qty, company)
    elif has_serial_no:
        locations = get_available_item_locations_for_serialized_item(
            item_code, from_warehouses, required_qty, company)
    elif has_batch_no:
        locations = get_available_item_locations_for_batched_item(
            item_code, from_warehouses, required_qty, company)
    else:
        locations = get_available_item_locations_for_other_item(
            item_code, from_warehouses, required_qty, company)

    total_qty_available = sum(location.get("qty") for location in locations)

    remaining_qty = required_qty - total_qty_available

    if remaining_qty > 0 and not ignore_validation:
        frappe.msgprint(
            _("{0} units of Item {1} is not available.").format(
                remaining_qty, frappe.get_desk_link("Item", item_code)),
            title=_("Insufficient Stock"),
        )

    return locations
Пример #5
0
def create_new_communication(created_by, next_action_by, row):
	comm = frappe.new_doc("Communication")
	comm.owner = created_by
	comm.user = next_action_by
	comm.communication_date = row.communication_date
	comm.duration = row.duration
	#add custom field for next_action_date in Communication
	#add custom field for communication_subtype in Communication
	if row.no_action_required != 1:
		comm.follow_up = 1
	comm.next_action_date = row.next_action_date #This would add a TODO to USER fields' account on that day
	comm.communication_subtype = "Sales Related"
	comm.communication_medium = row.type_of_communication 
	#Change the above Select field by customize form view in Communication
	comm.communication_type = "Communication"
	comm.content = row.details
	if row.document == "Customer":
		comm.reference_doctype = "Contact"
		comm.reference_name = row.contact
		comm.timeline_doctype = row.document
		comm.timeline_name = row.document_name
		comm.subject = "Sales Call: " + row.type_of_communication + " To:" + \
			row.document + ":" + row.document_name + " Contact:" + row.contact
	elif row.document == "Lead":
		comm.reference_doctype = row.document
		comm.reference_name = row.document_name
		comm.subject = "Sales Call: " + row.type_of_communication + " To:" + \
			row.document + ":" + row.document_name + " Org:" +  \
			row.lead_organisation_name + " Contact:" + row.lead_contact_name
	else:
		frappe.throw("Error Contact [email protected]")
	comm.insert()
	frappe.db.set_value('Daily Call Details', row.name, 'communication', comm.name)
	row.communication = comm.name
	frappe.msgprint("Created New Communication {}".format(frappe.get_desk_link('Communication', comm.name)))
Пример #6
0
def validate_carrier_tracking(doc,method):
	tracked_transporter = is_tracked_transporter(doc,method)
	if tracked_transporter == 1:

		frappe.msgprint(("{0} is Tracked Automatically all Shipment Data for LR No {1} \
				would be automatically updated in Carrier Tracking Document").format(
				frappe.get_desk_link('Transporters', doc.transporters), doc.lr_no))
	return tracked_transporter
Пример #7
0
def create_new_brc_tracking(doc,method):
	brc_doc = frappe.new_doc("BRC MEIS Tracking")
	brc_doc.flags.ignore_permissions = True
	brc_doc.export_or_import = 'Export'
	brc_doc.reference_doctype = doc.doctype
	brc_doc.reference_name = doc.name
	brc_doc.insert()
	frappe.msgprint(("Created New {0}").format(frappe.get_desk_link('BRC MEIS Tracking', brc_doc.name)))
Пример #8
0
	def validate_duplicate_log(self):
		doc = frappe.db.exists('Employee Checkin', {
			'employee': self.employee,
			'time': self.time,
			'name': ['!=', self.name]})
		if doc:
			doc_link = frappe.get_desk_link('Employee Checkin', doc)
			frappe.throw(_('This employee already has a log with the same timestamp.{0}')
				.format("<Br>" + doc_link))
Пример #9
0
def _delete_cashback(doc):
    cashback_receipt_name = frappe.db.exists("Cashback Receipt",
                                             {"origin": doc.name})
    if not cashback_receipt_name:
        return
    cashback_receipt = frappe.get_doc("Cashback Receipt",
                                      cashback_receipt_name)
    if len(cashback_receipt.redemptions) > 0:
        frappe.throw(
            _("{} cannot be cancelled because {} is redeemed.").format(
                frappe.get_desk_link("Sales Invoice", doc.name),
                "cancelled" if doc.docstatus == 2 else "returned",
                frappe.get_desk_link("Cashback Receipt",
                                     cashback_receipt_name),
            ))
    frappe.delete_doc("Cashback Receipt",
                      cashback_receipt.name,
                      ignore_permissions=True)
def _get_filters(doctype, filters):
    is_include = filters.vat_type not in ["Standard Rated", "Zero Rated"]
    vat_exempt_accounts = [
        x[0]
        for x in frappe.get_all(
            "POS Bahrain Settings Tax Category",
            filters={"category": filters.vat_type} if is_include else {},
            fields=["account"],
            as_list=1,
        )
    ]
    if not vat_exempt_accounts:
        msg = "Please setup {}: <em>VAT Tax Categories</em>".format(
            frappe.get_desk_link("POS Bahrain Settings", "")
        )
        if filters.get("hide_error_message"):
            raise VatCategoryNotFound(msg)
        else:
            frappe.throw(msg, exc=VatCategoryNotFound)

    inv_clauses = [
        "d.docstatus = 1",
        "d.posting_date BETWEEN %(from_date)s AND %(to_date)s",
        "IFNULL(dt.account_head, '') != ''",
        "dt.account_head {} %(tax_accounts)s".format("IN" if is_include else "NOT IN"),
    ]
    glp_clauses = concatv(
        inv_clauses, ["d.payment_type IN %(payment_types)s", "a.account_type = 'Tax'"]
    )
    values = merge(
        pick(["vat_type"], filters),
        {
            "from_date": filters.date_range[0],
            "to_date": filters.date_range[1],
            "tax_accounts": vat_exempt_accounts,
            "payment_types": ["Incoming"]
            if doctype == "Sales Invoice"
            else ["Outgoing", "Internal Transfer"],
        },
    )
    return (
        {
            "doctype": doctype,
            "item_doctype": "{} Item".format(doctype),
            "tax_doctype": "{} Taxes and Charges".format(
                "Sales" if doctype == "Sales Invoice" else "Purchase"
            ),
            "party_name": "{}_name".format(
                "customer" if doctype == "Sales Invoice" else "supplier"
            ),
            "invoice_clauses": " AND ".join(inv_clauses),
            "glp_clauses": " AND ".join(glp_clauses),
        },
        values,
    )
Пример #11
0
def validate_negative_qty_in_future_sle(args, allow_negative_stock=None):
    allow_negative_stock = allow_negative_stock \
     or cint(frappe.db.get_single_value("Stock Settings", "allow_negative_stock"))

    if args.actual_qty < 0 and not allow_negative_stock:
        sle = get_future_sle_with_negative_qty(args)
        if sle:
            message = _(
                "{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
            ).format(
                abs(sle[0]["qty_after_transaction"]),
                frappe.get_desk_link('Item', args.item_code),
                frappe.get_desk_link('Warehouse', args.warehouse),
                sle[0]["posting_date"], sle[0]["posting_time"],
                frappe.get_desk_link(sle[0]["voucher_type"],
                                     sle[0]["voucher_no"]))

            frappe.throw(message,
                         NegativeStockError,
                         title='Insufficient Stock')
Пример #12
0
def validate(doc, method):
	if doc.reference_type == 'Communication':
		if doc.reference_name:
			comm_doc = frappe.get_doc('Communication', doc.reference_name)
		else:
			frappe.throw('Reference Name is Mandatory for {} Reference Type'.format(doc.reference_name))
		if comm_doc.follow_up == 1 and doc.status == 'Closed':
			frappe.msgprint("If you don't wish to receive ToDo for this Communication \
				then Click on Communication and uncheck the Follow Up Check Box \
				or Change the next action date to be reminded again about this communication \
				{}".format(frappe.get_desk_link("Communication", doc.reference_name)))
Пример #13
0
def create_new_ship_track(si_doc):
	track = frappe.new_doc("Carrier Tracking")
	track.carrier_name = si_doc.transporters
	track.awb_number = si_doc.lr_no
	track.receiver_document = "Customer"
	track.receiver_name = si_doc.customer
	track.document = "Sales Invoice"
	track.document_name = si_doc.name
	track.flags.ignore_permissions = True
	track.insert()
	frappe.msgprint(("Created New {0}").format(frappe.get_desk_link('Carrier Tracking', track.name)))
	def raise_exceptions(self):
		deficiency = min(e["diff"] for e in self.exceptions)

		if ((self.exceptions[0]["voucher_type"], self.exceptions[0]["voucher_no"]) in
			frappe.local.flags.currently_saving):

			msg = _("{0} units of {1} needed in {2} to complete this transaction.").format(
				abs(deficiency), frappe.get_desk_link('Item', self.item_code),
				frappe.get_desk_link('Warehouse', self.warehouse))
		else:
			msg = _("{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction.").format(
				abs(deficiency), frappe.get_desk_link('Item', self.item_code),
				frappe.get_desk_link('Warehouse', self.warehouse),
				self.exceptions[0]["posting_date"], self.exceptions[0]["posting_time"],
				frappe.get_desk_link(self.exceptions[0]["voucher_type"], self.exceptions[0]["voucher_no"]))

		if self.verbose:
			frappe.throw(msg, NegativeStockError, title='Insufficent Stock')
		else:
			raise NegativeStockError(msg)
Пример #15
0
 def _validate_collected_booking_orders(self):
     for bo_name in set(x.booking_order
                        for x in self.on_loads + self.off_loads):
         status = frappe.get_cached_value("Booking Order", bo_name,
                                          "status")
         if status == "Collected":
             frappe.throw(
                 frappe._("Cannot cancel this Loading Operation contains "
                          "{} which is already Collected.".format(
                              frappe.get_desk_link("Booking Order",
                                                   bo_name))))
Пример #16
0
def create_new_ship_track(si_doc):
    track = frappe.new_doc("Carrier Tracking")
    track.carrier_name = si_doc.transporters
    track.awb_number = si_doc.lr_no
    track.receiver_document = "Customer"
    track.receiver_name = si_doc.customer
    track.document = "Sales Invoice"
    track.document_name = si_doc.name
    # track.shipment_package_details = [{"shipment_package":"PKG00001", "package_weight":1, "weight_uom":"Kg"}]
    track.flags.ignore_permissions = True
    track.insert()
    frappe.msgprint(("Created New {0}").format(frappe.get_desk_link('Carrier Tracking', track.name)))
Пример #17
0
 def validate_duplicate_log(self):
     doc = frappe.db.exists(
         "Employee Checkin", {
             "employee": self.employee,
             "time": self.time,
             "name": ["!=", self.name]
         })
     if doc:
         doc_link = frappe.get_desk_link("Employee Checkin", doc)
         frappe.throw(
             _("This employee already has a log with the same timestamp.{0}"
               ).format("<Br>" + doc_link))
 def _validate_default(self):
     existing = frappe.db.exists(
         "Booking Order Charge Template",
         {
             "is_default": 1,
             "name": ("!=", self.name)
         },
     )
     if existing:
         frappe.throw(
             frappe._("{} is already the default template".format(
                 frappe.get_desk_link("Booking Order Charge Template",
                                      existing))))
Пример #19
0
def _get_filters(doctype, filters):
    vat_exempt_accounts = [
        x[0] for x in frappe.get_all(
            "POS Bahrain Settings Tax Exempt", fields=["account"], as_list=1)
    ]
    if not vat_exempt_accounts:
        frappe.throw(
            frappe._("Please set {}: <em>VAT Exempt Accounts</em>".format(
                frappe.get_desk_link("POS Bahrain Settings", ""))))
    inv_clauses = [
        "d.docstatus = 1",
        "d.posting_date BETWEEN %(from_date)s AND %(to_date)s",
        "IFNULL(dt.account_head, '') != ''",
        "dt.account_head {} %(tax_accounts)s".format(
            "IN" if filters.vat_type == "exempt" else "NOT IN"),
    ]
    glp_clauses = concatv(
        inv_clauses,
        ["d.payment_type IN %(payment_types)s", "a.account_type = 'Tax'"])
    values = merge(
        pick(["vat_type"], filters),
        {
            "from_date":
            filters.date_range[0],
            "to_date":
            filters.date_range[1],
            "tax_accounts":
            vat_exempt_accounts,
            "payment_types": ["Incoming"] if doctype == "Sales Invoice" else
            ["Outgoing", "Internal Transfer"],
        },
    )
    return (
        {
            "doctype":
            doctype,
            "item_doctype":
            "{} Item".format(doctype),
            "tax_doctype":
            "{} Taxes and Charges".format("Sales" if doctype ==
                                          "Sales Invoice" else "Purchase"),
            "party_name":
            "{}_name".format("customer" if doctype ==
                             "Sales Invoice" else "supplier"),
            "invoice_clauses":
            " AND ".join(inv_clauses),
            "glp_clauses":
            " AND ".join(glp_clauses),
        },
        values,
    )
def get_available_item_locations(item_code, from_warehouses, required_qty, company, ignore_validation=False):
	locations = []
	locations = get_available_item_locations_for_other_item(item_code, from_warehouses, required_qty, company)

	total_qty_available = sum(location.get('qty') for location in locations)

	remaining_qty = required_qty - total_qty_available

	if remaining_qty > 0 and not ignore_validation:
		frappe.msgprint(_('{0} units of Item {1} is not available.')
			.format(remaining_qty, frappe.get_desk_link('Item', item_code)),
			title=_("Insufficient Stock"))

	return locations
Пример #21
0
def validate(doc, method):
    if doc.reference_type == 'Communication':
        if doc.reference_name:
            comm_doc = frappe.get_doc('Communication', doc.reference_name)
        else:
            frappe.throw(
                'Reference Name is Mandatory for {} Reference Type'.format(
                    doc.reference_name))
        if comm_doc.follow_up == 1 and doc.status == 'Closed':
            frappe.msgprint(
                "If you don't wish to receive ToDo for this Communication \
				then Click on Communication and uncheck the Follow Up Check Box \
				or Change the next action date to be reminded again about this communication \
				{}".format(frappe.get_desk_link("Communication", doc.reference_name)))
Пример #22
0
    def raise_exceptions(self):
        msg_list = []
        for warehouse, exceptions in iteritems(self.exceptions):
            deficiency = min(e["diff"] for e in exceptions)

            if ((exceptions[0]["voucher_type"], exceptions[0]["voucher_no"])
                    in frappe.local.flags.currently_saving):

                msg = _(
                    "{0} units of {1} needed in {2} to complete this transaction."
                ).format(
                    abs(deficiency),
                    frappe.get_desk_link('Item', exceptions[0]["item_code"]),
                    frappe.get_desk_link('Warehouse', warehouse))
            else:
                msg = _(
                    "{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
                ).format(
                    abs(deficiency),
                    frappe.get_desk_link('Item', exceptions[0]["item_code"]),
                    frappe.get_desk_link('Warehouse', warehouse),
                    exceptions[0]["posting_date"],
                    exceptions[0]["posting_time"],
                    frappe.get_desk_link(exceptions[0]["voucher_type"],
                                         exceptions[0]["voucher_no"]))

            if msg:
                msg_list.append(msg)

        if msg_list:
            message = "\n\n".join(msg_list)
            if self.verbose:
                frappe.throw(message,
                             NegativeStockError,
                             title='Insufficient Stock')
            else:
                raise NegativeStockError(message)
Пример #23
0
def _validate_freight_qty(doc):
    bo = frappe.get_cached_doc("Booking Order", doc.gg_booking_order)
    get_freight_row = compose(
        excepts(StopIteration, first, lambda _: None),
        lambda x: filter(lambda row: row.name == x, bo.freight),
    )

    for item in doc.items:
        if item.gg_bo_detail:
            freight_row = get_freight_row(item.gg_bo_detail)
            if not freight_row:
                frappe.throw(
                    frappe.
                    _("Invalid Booking Order Freight Detail found in row #{} for {}"
                      .format(item.idx,
                              frappe.get_desk_link("Sales Invoice",
                                                   doc.name))))

            total_qty = (frappe.get_all(
                "Sales Invoice Item",
                filters={
                    "docstatus": 1,
                    "gg_bo_detail": item.gg_bo_detail
                },
                fields=["sum(qty)"],
                as_list=1,
            )[0][0] or 0)
            if total_qty + item.qty > _get_freight_qty(freight_row):
                frappe.throw(
                    frappe.
                    _("Total Qty in #{} for {} will exceed Freight Qty declared in {}"
                      .format(
                          item.idx,
                          frappe.get_desk_link("Sales Invoice", doc.name),
                          frappe.get_desk_link("Booking Order",
                                               doc.gg_booking_order),
                      )))
Пример #24
0
	def validate_default_permission(self):
		''' validate user permission overlap for default value of a particular doctype '''
		overlap_exists = []
		if self.is_default:
			overlap_exists = frappe.get_all(self.doctype, filters={
				'allow': self.allow,
				'user': self.user,
				'is_default': 1,
				'name': ['!=', self.name]
			}, or_filters={
				'applicable_for': cstr(self.applicable_for),
				'apply_to_all_doctypes': 1
			}, limit=1)
		if overlap_exists:
			ref_link = frappe.get_desk_link(self.doctype, overlap_exists[0].name)
			frappe.throw(_("{0} has already assigned default value for {1}.".format(ref_link, self.allow)))
Пример #25
0
	def validate_default_permission(self):
		"""validate user permission overlap for default value of a particular doctype"""
		overlap_exists = []
		if self.is_default:
			overlap_exists = frappe.get_all(
				self.doctype,
				filters={"allow": self.allow, "user": self.user, "is_default": 1, "name": ["!=", self.name]},
				or_filters={
					"applicable_for": cstr(self.applicable_for),
					"apply_to_all_doctypes": 1,
				},
				limit=1,
			)
		if overlap_exists:
			ref_link = frappe.get_desk_link(self.doctype, overlap_exists[0].name)
			frappe.throw(_("{0} has already assigned default value for {1}.").format(ref_link, self.allow))
Пример #26
0
def validate(doc, method):
    def get_error_type():
        if doc.gg_loading_operation:
            existing = frappe.db.exists(
                "Sales Invoice",
                {
                    "name": ("!=", doc.name),
                    "docstatus": 1,
                    "gg_booking_order": doc.gg_booking_order,
                    "gg_loading_operation": doc.gg_loading_operation,
                },
            )
            if existing:
                return "freight"
        else:
            existing = frappe.db.sql(
                """
                    SELECT COUNT(name) FROM `tabSales Invoice` WHERE
                        name != %(name)s AND
                        docstatus = 1 AND
                        gg_booking_order = %(booking_order)s AND
                        IFNULL(gg_loading_operation, '') = ''
                """,
                values={
                    "name": doc.name,
                    "booking_order": doc.gg_booking_order
                },
            )[0][0]
            if existing:
                return "charges"
        return None

    if doc.gg_booking_order:
        error_type = get_error_type()
        if error_type:
            frappe.throw(
                frappe.
                _("Sales Invoice for {} already existing for {}. ".format(
                    error_type,
                    frappe.get_desk_link("Booking Order",
                                         doc.gg_booking_order),
                ) +
                  "If you want to proceed, please cancel the previous Invoice."
                  ))

        if doc.flags.validate_loading and doc.gg_loading_operation:
            _validate_freight_qty(doc)
Пример #27
0
def get_available_item_locations(item_code, from_warehouses, required_qty, company):
	locations = []
	if frappe.get_cached_value('Item', item_code, 'has_serial_no'):
		locations = get_available_item_locations_for_serialized_item(item_code, from_warehouses, required_qty, company)
	elif frappe.get_cached_value('Item', item_code, 'has_batch_no'):
		locations = get_available_item_locations_for_batched_item(item_code, from_warehouses, required_qty, company)
	else:
		locations = get_available_item_locations_for_other_item(item_code, from_warehouses, required_qty, company)

	total_qty_available = sum(location.get('qty') for location in locations)

	remaining_qty = required_qty - total_qty_available

	if remaining_qty > 0:
		frappe.msgprint(_('{0} units of {1} is not available.')
			.format(remaining_qty, frappe.get_desk_link('Item', item_code)))

	return locations
Пример #28
0
 def validate(self):
     existing_loading_unit = frappe.db.get_value(
         "Booking Log",
         filters={
             "name": ("!=", self.name),
             "booking_order": self.booking_order,
             "activity": ("!=", "Booked"),
         },
         fieldname="loading_unit",
     )
     if existing_loading_unit and self.loading_unit != existing_loading_unit:
         frappe.throw(
             frappe.
             _("Previous Loading Operation on {} has already being performed based on {}. "
               .format(
                   frappe.get_desk_link("Booking Order",
                                        self.booking_order),
                   existing_loading_unit,
               ) +
               "Please execute the current one based on the same unit."))
Пример #29
0
    def on_cancel(self):
        for (log_name, ) in frappe.get_all(
                "Booking Log", filters={"booking_order":
                                        self.name}, as_list=1):
            frappe.delete_doc("Booking Log", log_name, ignore_permissions=True)

        for (si_name, ) in frappe.get_all(
                "Sales Invoice",
                filters={
                    "docstatus": 1,
                    "gg_booking_order": self.name
                },
                as_list=1,
        ):
            si = frappe.get_doc("Sales Invoice", si_name)
            if si.status == "Paid":
                frappe.throw(
                    frappe._("Cannot cancel Paid invoice {}".format(
                        frappe.get_desk_link("Sales Invoice", si_name))))
            si.flags.ignore_permissions = True
            si.cancel()
Пример #30
0
def new_brc_tracking(doc,method):
	#If SI is from Cancelled DOC then UPDATE the details of same in BRC
	stct_doc = frappe.get_doc("Sales Taxes and Charges Template", doc.taxes_and_charges)
	add_doc = frappe.get_doc("Address", doc.shipping_address_name)
	if stct_doc.is_export == 1 and add_doc.country != "India":
		if doc.amended_from:
			is_exist = frappe.db.sql("""SELECT name FROM `tabBRC MEIS Tracking` WHERE reference_name = '%s'
				""" %(doc.amended_from), as_list=1)
			if not is_exist:
				create_new_brc_tracking(doc,method)
			else:
				exist_brc = frappe.get_doc("BRC MEIS Tracking", is_exist[0][0])
				exist_brc.reference_name = doc.name
				exist_brc.flags.ignore_permissions = True
				exist_brc.save()
				frappe.msgprint(("Updated {0}").format(frappe.get_desk_link('BRC MEIS Tracking', exist_brc.name)))
		else:
			is_exist = frappe.db.sql("""SELECT name FROM `tabBRC MEIS Tracking` WHERE reference_name = '%s'
				""" %(doc.name), as_list=1)
			if not is_exist:
				create_new_brc_tracking(doc,method)
Пример #31
0
def get_alert_dict(doc):
    alert_dict = frappe._dict()
    owner_name = get_fullname(doc.owner)
    doc_link = frappe.get_desk_link(doc.reference_doctype, doc.reference_name)
    points = doc.points
    bold_points = frappe.bold(doc.points)
    if doc.type == 'Auto':
        if points == 1:
            message = _('You gained {0} point')
        else:
            message = _('You gained {0} points')
        alert_dict.message = message.format(bold_points)
        alert_dict.indicator = 'green'
    elif doc.type == 'Appreciation':
        if points == 1:
            message = _('{0} appreciated your work on {1} with {2} point')
        else:
            message = _('{0} appreciated your work on {1} with {2} points')
        alert_dict.message = message.format(owner_name, doc_link, bold_points)
        alert_dict.indicator = 'green'
    elif doc.type == 'Criticism':
        if points == 1:
            message = _('{0} criticized your work on {1} with {2} point')
        else:
            message = _('{0} criticized your work on {1} with {2} points')

        alert_dict.message = message.format(owner_name, doc_link, bold_points)
        alert_dict.indicator = 'red'
    elif doc.type == 'Revert':
        if points == 1:
            message = _('{0} reverted your point on {1}')
        else:
            message = _('{0} reverted your points on {1}')
        alert_dict.message = message.format(
            owner_name,
            doc_link,
        )
        alert_dict.indicator = 'red'

    return alert_dict
Пример #32
0
def create_new_communication(created_by, next_action_by, row):
    comm = frappe.new_doc("Communication")
    comm.owner = created_by
    comm.user = next_action_by
    comm.communication_date = row.communication_date
    comm.duration = row.duration
    comm.sender = created_by
    #add custom field for next_action_date in Communication
    #add custom field for communication_subtype in Communication
    if row.no_action_required != 1:
        comm.follow_up = 1
    comm.next_action_date = row.next_action_date  #This would add a TODO to USER fields' account on that day
    comm.communication_subtype = "Sales Related"
    comm.communication_medium = row.type_of_communication
    #Change the above Select field by customize form view in Communication
    comm.communication_type = "Communication"
    comm.content = row.details
    if row.document == "Customer":
        comm.reference_doctype = "Contact"
        comm.reference_name = row.contact
        comm.timeline_doctype = row.document
        comm.timeline_name = row.document_name
        comm.subject = "Sales Call: " + row.type_of_communication + " To:" + \
         row.document + ":" + row.document_name + " Contact:" + row.contact
    elif row.document == "Lead":
        comm.reference_doctype = row.document
        comm.reference_name = row.document_name
        comm.subject = "Sales Call: " + row.type_of_communication + " To:" + \
         row.document + ":" + row.document_name + " Org:" +  \
         row.lead_organisation_name + " Contact:" + row.lead_contact_name
    else:
        frappe.throw("Error Contact [email protected]")
    comm.insert()
    frappe.db.set_value('Daily Call Details', row.name, 'communication',
                        comm.name)
    row.communication = comm.name
    frappe.msgprint("Created New Communication {}".format(
        frappe.get_desk_link('Communication', comm.name)))
Пример #33
0
    def create_customer(self):
        if self.customer:
            frappe.throw(
                frappe._("Customer already created for {}".format(
                    frappe.get_desk_link("Booking Party", self.name))))

        doc = frappe.get_doc({
            "doctype":
            "Customer",
            "customer_name":
            self.booking_party_name,
            "customer_group":
            frappe.get_cached_value("Selling Settings", None,
                                    "customer_group"),
            "territory":
            frappe.get_cached_value("Selling Settings", None, "territory"),
            "customer_primary_address":
            self.primary_address,
        }).insert(ignore_permissions=True, ignore_mandatory=True)
        for (parent, ) in frappe.get_all(
                "Dynamic Link",
                filters={
                    "parenttype": "Address",
                    "link_doctype": "Booking Party",
                    "link_name": self.name,
                },
                fields=["parent"],
                as_list=1,
        ):
            address = frappe.get_doc("Address", parent)
            address.append("links", {
                "link_doctype": doc.doctype,
                "link_name": doc.name
            })
            address.save(ignore_permissions=True)

        self.db_set("customer", doc.name)
        return doc
Пример #34
0
def validate_negative_qty_in_future_sle(args, allow_negative_stock=False):
	if allow_negative_stock or is_negative_stock_allowed(item_code=args.item_code):
		return
	if not (args.actual_qty < 0 or args.voucher_type == "Stock Reconciliation"):
		return

	neg_sle = get_future_sle_with_negative_qty(args)
	if neg_sle:
		message = _(
			"{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
		).format(
			abs(neg_sle[0]["qty_after_transaction"]),
			frappe.get_desk_link("Item", args.item_code),
			frappe.get_desk_link("Warehouse", args.warehouse),
			neg_sle[0]["posting_date"],
			neg_sle[0]["posting_time"],
			frappe.get_desk_link(neg_sle[0]["voucher_type"], neg_sle[0]["voucher_no"]),
		)

		frappe.throw(message, NegativeStockError, title=_("Insufficient Stock"))

	if not args.batch_no:
		return

	neg_batch_sle = get_future_sle_with_negative_batch_qty(args)
	if neg_batch_sle:
		message = _(
			"{0} units of {1} needed in {2} on {3} {4} for {5} to complete this transaction."
		).format(
			abs(neg_batch_sle[0]["cumulative_total"]),
			frappe.get_desk_link("Batch", args.batch_no),
			frappe.get_desk_link("Warehouse", args.warehouse),
			neg_batch_sle[0]["posting_date"],
			neg_batch_sle[0]["posting_time"],
			frappe.get_desk_link(neg_batch_sle[0]["voucher_type"], neg_batch_sle[0]["voucher_no"]),
		)
		frappe.throw(message, NegativeStockError, title=_("Insufficient Stock for Batch"))
Пример #35
0
	def validate(self):
		if self.call_details:
			for row in self.call_details:
				if row.communication:
					frappe.throw('Communication {} already exists for Row# {}'.\
						format(frappe.get_desk_link('Communication', row.communication), row.idx))
				if row.document == "Customer":
					if row.document_name:
						if row.contact:
							check_contact(row.document, row.document_name, row.contact)
						else:
							row.contact = check_contact(row.document, row.document_name, row.contact)[0][0]
					else:
						frappe.throw("Customer is Mandatory")
				elif row.document == "Lead":
					#Check if Lead is converted
					if row.document_name:
						lead = frappe.get_doc("Lead", row.document_name)
						if not row.lead_status:
							row.lead_status = lead.status
						else:
							if row.lead_status != lead.status:
								update_lead_status(lead, row.lead_status)
						row.lead_contact_name = lead.lead_name
						row.lead_organisation_name = lead.company_name
						if lead.status == "Converted":
							customer = frappe.db.sql("""SELECT name FROM `tabCustomer` 
								WHERE lead_name = '%s'""" %(row.document_name), as_list=1)
							if customer:
								frappe.throw(("Selected Lead is already converted to {}. \n\
									Please select the customer and not this Lead in Row # {}.").\
									format(frappe.get_desk_link("Customer", customer[0][0]), \
										row.idx))
							else:
								frappe.throw("Selected Lead {} in Row# {} is Marked as Converted. \n\
									Either Change the Lead Status or Link it with a Customer. \n\
									Since No Customer is Linked to this Lead".\
									format(frappe.get_desk_link("Lead", row.document_name), row.idx))
				else:
					frappe.throw("Document Field is Mandatory")
				if row.communication_date:
					if self.allow_back_dated_entries == 1:
						back_dated_days = self.back_dated_days
					else:
						back_dated_days = 0
					check_date_time_diff(row.communication_date, days_diff=(-1*back_dated_days), \
						type_of_check='date', name_of_field = 'Communication')
				else:
					frappe.throw("Communication Date is Mandatory")
				if row.next_action_date:
					check_date_time_diff(row.next_action_date, hours_diff=1, \
						type_of_check= 'time', name_of_field = 'Next Action')
				if not row.type_of_communication:
					frappe.throw('Type of Communication is Mandatory')
				if not row.details:
					frappe.throw('Details of Communication are Mandatory')
			
			if row.no_action_required == 1:
				#Check only System Managers can do this Entry
				user = frappe.session.user
				roles = frappe.db.sql("""SELECT role from `tabUserRole` where parent = '%s' """ \
					%user, as_list=1)
				row.next_action_date = ""
			else:
				if not row.next_action_date:
					frappe.throw("Please add a Next Action Date")
		else:
			frappe.throw("Enter Call Details before creating Communications")
		
		if self.created_by:
			pass
		else:
			frappe.throw("Mandatory Field Created By")
		
		if self.next_action_by:
			pass
		else:
			frappe.throw("Mandatory Field Next Action By")