Beispiel #1
0
def daily_check():
    month = frappe.get_single("Einstellungen").execution_month
    day = frappe.get_single("Einstellungen").execution_day
    today = getdate(now())

    # check for execution
    if str(month) == today.strftime("%-m"):
        if str(day) == today.strftime("%-d"):
            relevant_date = today.strftime("%Y-%m-%d")
            check_affected_sinvs(relevant_date)
            return

    # check for mail Notifications
    day_diff = date_diff(
        '{year}-{month}-{day}'.format(year=today.strftime("%Y"),
                                      month=month,
                                      day=day), now())

    if day_diff == 7:
        send_pre_week_reminder()
        return

    if day_diff == 2:
        send_two_day_reminder()
        return
Beispiel #2
0
def sync_plant(data):
	barcode = data.get("id")
	name = frappe.db.sql_list("select name from tabPlant where name=%(barcode)s or bio_barcode=%(barcode)s", {"barcode": barcode})

	if name:
		name = name.pop()
		doc = frappe.get_doc("Plant", name)
		if doc.get("bio_transaction_id") == data.get("transactionid"):
			frappe.db.set_value("Plant", name, "bio_last_sync", now(), update_modified=False)
			return False
	else:
		sessiontime = datetime.datetime.fromtimestamp(cint(data.get("sessiontime")))
		doc = frappe.get_doc({
			"__islocal": 1,
			"doctype": "Plant",
			"bio_barcode": barcode,
			"posting_date": sessiontime.strftime(DATE_FORMAT),
			"posting_time": sessiontime.strftime(TIME_FORMAT)
		})


	plant_room = frappe.get_doc("Plant Room", {"bio_id": data.get("room")})
	doc.update({
		"strain": find_strain(data.get("strain")),
		"plant_room": plant_room.get("name") if plant_room else "",
		"is_mother_plant": cint(data.get("mother")),
		"destroy_scheduled": cint(data.get("removescheduled")),
		"harvest_collect": cint(data.get("harvestcollect")),
		"cure_collect": cint(data.get("curecollect")),
		"bio_transaction_id": cint(data.get("transactionid")),
		"bio_last_sync": now(),
		"disabled": 0,
	})

	item_values = get_item_values(data.get("parentid"), ["name", "item_group"])
	if item_values:
		item, item_group = item_values
		doc.item = item
		doc.item_group = item_group

	if doc.get("destroy_scheduled") and data.get("removescheduletime"):
		doc.remove_time = datetime.datetime.fromtimestamp(cint(data.get("removescheduletime"))).strftime(DATETIME_FORMAT)

		if data.get("removereason"):
			doc.remove_reason = data.get("removereason")

	state = cint(data.get("state"))
	doc.state = "Drying" if state == 1 else ("Cured" if state == 2 else "Growing")

	doc.flags.in_import = True
	doc.flags.ignore_validate_update_after_submit = True
	doc.flags.ignore_mandatory = True

	if doc.is_new():
		doc.submit()
	else:
		doc.save()

	frappe.db.commit()
Beispiel #3
0
def destroy_scheduled_plants():
	"""Destroy expired Plants"""
	date = add_to_date(now(), days=-3)
	for name in frappe.get_list("Plant",
								[["disabled", "=", 0], ["destroy_scheduled", "=", 1], ["remove_time", "<", date]]):
		plant = frappe.get_doc("Plant", name)
		plant.disabled = 1
		plant.remove_time = now()
		plant.flags.ignore_validate_update_after_submit = True
		plant.save()
Beispiel #4
0
def disable_deleted_items(sync_time=None):
	if not sync_time:
		sync_time = now()

	return frappe.db.sql(
		"update tabItem set `bio_remaining_quantity` = 0, `disabled` = 1 where transaction_id IS NOT NULL and (`bio_last_sync` IS NULL or `bio_last_sync` < %(bio_last_sync)s)",
		{"bio_last_sync": sync_time})
Beispiel #5
0
def disable_deleted_items(sync_time=None):
    if not sync_time:
        sync_time = now()

    return frappe.db.sql(
        "update tabItem set `bio_remaining_quantity` = 0, `disabled` = 1 where transaction_id IS NOT NULL and (`bio_last_sync` IS NULL or `bio_last_sync` < %(bio_last_sync)s)",
        {"bio_last_sync": sync_time})
Beispiel #6
0
def bulk_clone(name):
	source_plant = frappe.get_doc("Plant", name)

	if source_plant.qty > 1:
		warehouse = frappe.get_doc("Warehouse", source_plant.get("warehouse"))
		location = frappe.get_value("BioTrack Settings", None, "location")
		remaining_qty = source_plant.qty - 1

		result = biotrackthc_call("plant_new", {
			"room": warehouse.external_id,
			"quantity": remaining_qty,
			"strain": source_plant.strain,
			"source": source_plant.item_code,
			"mother": cint(source_plant.get("is_mother")),
			"location": location
		})

		for barcode in result.get("barcode_id"):
			plant = frappe.new_doc("Plant")
			plant.update({
				"barcode": barcode,
				"item_group": source_plant.item_group,
				"source": source_plant.item_code,
				"strain": source_plant.strain,
				"warehouse": source_plant.warehouse,
				"state": source_plant.state,
				"birthdate": now(),
			})

			plant.save()

		# save directly with sql to avoid mistimestamp check
		frappe.db.set_value("Plant", source_plant.name, "qty", 1, update_modified=False)
		frappe.publish_realtime("list_update", {"doctype": "Plant"})
Beispiel #7
0
    def test_corrective_costing(self):
        job_card = frappe.get_last_doc("Job Card",
                                       {"work_order": self.work_order.name})

        job_card.append(
            "time_logs",
            {
                "from_time": now(),
                "to_time": add_to_date(now(), hours=1),
                "completed_qty": 2
            },
        )
        job_card.submit()

        self.work_order.reload()
        original_cost = self.work_order.total_operating_cost

        # Create a corrective operation against it
        corrective_action = frappe.get_doc(
            doctype="Operation",
            is_corrective_operation=1,
            name=frappe.generate_hash()).insert()

        corrective_job_card = make_corrective_job_card(
            job_card.name,
            operation=corrective_action.name,
            for_operation=job_card.operation)
        corrective_job_card.hour_rate = 100
        corrective_job_card.insert()
        corrective_job_card.append(
            "time_logs",
            {
                "from_time": add_to_date(now(), hours=2),
                "to_time": add_to_date(now(), hours=2, minutes=30),
                "completed_qty": 2,
            },
        )
        corrective_job_card.submit()

        self.work_order.reload()
        cost_after_correction = self.work_order.total_operating_cost
        self.assertGreater(cost_after_correction, original_cost)

        corrective_job_card.cancel()
        self.work_order.reload()
        cost_after_cancel = self.work_order.total_operating_cost
        self.assertEqual(cost_after_cancel, original_cost)
Beispiel #8
0
def create_log_record(positiv_log, negativ_log):
    log = frappe.get_doc({
        "doctype": "Customer Deactivation Log",
        "executed_on": getdate(now()),
        "deactivations": positiv_log,
        "errors": negativ_log
    })
    log.insert()
Beispiel #9
0
	def harvest_schedule(self):
		if self.harvest_scheduled:
			frappe.throw("Plant <strong>{}</strong> has been scheduled for harvest.".format(self.name))

		if not self.flags.ignore_hooks:
			self.run_method("on_harvest_schedule")

		self.harvest_scheduled = 1
		self.harvest_schedule_time = now()

		self.flags.ignore_validate_update_after_submit = True
		self.save()
Beispiel #10
0
def sync():
	frappe.flags.in_import = True
	sync_time = now()

	biotrack_plants = get_biotrack_plants()
	for biotrack_plant in biotrack_plants:
		sync_plant(biotrack_plant)

	disable_deleted_plants(sync_time)
	frappe.flags.in_import = False

	return len(biotrack_plants)
Beispiel #11
0
def sync():
    frappe.flags.in_import = True
    sync_time = now()

    biotrack_plants = get_biotrack_plants()
    for biotrack_plant in biotrack_plants:
        sync_plant(biotrack_plant)

    disable_deleted_plants(sync_time)
    frappe.flags.in_import = False

    return len(biotrack_plants)
Beispiel #12
0
	def convert_to_inventory(self):
		item_group = frappe.get_doc("Item Group", {"external_id": 12})  # Mature Plant
		qty = 1
		item = self.collect_item(item_group, qty)

		# destroy plant as well
		self.destroy_scheduled = 1
		self.remove_time = now()
		self.disabled = 1

		self.flags.ignore_validate_update_after_submit = True
		self.save()

		self.run_method('after_convert_to_inventory', item=item)
Beispiel #13
0
	def destroy_schedule(self, reason, reason_txt=None, override=None):
		if self.destroy_scheduled and not override:
			frappe.throw(
				"Plant <strong>{}</strong> has already been scheduled for destruction.".format(
					self.name))

		reason_type = removal_reasons.keys()[removal_reasons.values().index(reason)]

		if not self.flags.ignore_hooks:
			self.run_method("on_destroy_schedule", reason_type=reason_type, reason=reason_txt, override=override)

		self.destroy_scheduled = 1
		self.remove_reason = reason_txt or reason
		self.remove_time = now()
		self.flags.ignore_validate_update_after_submit = True
		self.save()
Beispiel #14
0
def sync():
	"""Manual execute: bench execute erpnext_biotrack.biotrackthc.inventory.sync"""
	success = 0
	sync_time = now()
	samples = []

	for inventory in get_biotrack_inventories():
		if inventory.get("is_sample"):
			samples.append(inventory)
			continue

		if sync_item(inventory):
			success += 1

	disable_deleted_items(sync_time)
	syn_samples(samples)

	return success, 0
Beispiel #15
0
def sync():
    """Manual execute: bench execute erpnext_biotrack.biotrackthc.inventory.sync"""
    success = 0
    sync_time = now()
    samples = []

    for inventory in get_biotrack_inventories():
        if inventory.get("is_sample"):
            samples.append(inventory)
            continue

        if sync_item(inventory):
            success += 1

    disable_deleted_items(sync_time)
    syn_samples(samples)

    return success, 0
Beispiel #16
0
def sync_item(data):
    barcode = str(data.get("id"))
    remaining_quantity = flt(data.get("remaining_quantity"))
    name = None

    item_values = get_item_values(barcode, ["name", "transaction_id"])
    if item_values:
        name, transaction_id = item_values
        if not (frappe.flags.force_sync
                or False) and transaction_id == data.get("transactionid"):
            frappe.db.set_value("Item",
                                name,
                                "bio_last_sync",
                                now(),
                                update_modified=False)
            return False

    # inventory type
    item_group = find_item_group(data)
    warehouse = find_warehouse(data)
    current_remaining_quantity = 0

    # product (Item) mapping
    if data.get("productname"):
        item_name = data.get("productname")
    else:
        item_name = " ".join(
            filter(None, [data.get("strain"), item_group.name]))

    if not name:
        item_code = barcode
        item = frappe.get_doc({
            "doctype": "Item",
            "item_code": item_code,
            "item_name": item_name,
            "bio_barcode": barcode,
            "is_stock_item": 1,
            "stock_uom": "Gram",
            "item_group": item_group.name,
            "default_warehouse": warehouse.name,
        })
    else:
        item = frappe.get_doc("Item", name)
        current_remaining_quantity = item.bio_remaining_quantity

    strain = ""
    if data.get("strain"):
        strain = find_strain(data.get("strain"))

    # Post task will do on biotrack_after_sync hook
    parent_ids = data.get("parentid")
    plant_ids = data.get("plantid")
    if not item.is_lot_item and (parent_ids or plant_ids):
        item.set(
            "linking_data",
            json.dumps({
                "parent_ids": parent_ids,
                "plant_ids": plant_ids
            }))

    item.update({
        "item_name": item_name,
        "bio_barcode": barcode,
        "strain": strain,
        "bio_remaining_quantity": remaining_quantity,
        "transaction_id": data.get("transactionid"),
        "bio_last_sync": now(),
        "disabled": 1 if remaining_quantity == 0 else 0,
    })

    item.flags.ignore_links = True
    item.save()

    # adjust_stock
    if item.is_stock_item:
        if remaining_quantity > current_remaining_quantity:
            make_stock_entry(item_code=item.name,
                             target=item.default_warehouse,
                             qty=remaining_quantity -
                             current_remaining_quantity)

        # Consider to not modified down item's balance because it's hard to figure out the correct warehouse and its balance to deduct
        # elif remaining_quantity < current_remaining_quantity:
        # 	posting_date, posting_time = nowdate(), nowtime()
        # 	balance = get_stock_balance_for(item.name, item.default_warehouse, posting_date, posting_time)
        #
        # 	if balance["qty"] >= remaining_quantity:
        # 		make_stock_entry(item_code=item.name, source=item.default_warehouse,
        # 					 qty=current_remaining_quantity - remaining_quantity)

    # Disable Usable Marijuana item does not have product name
    if not data.get("productname") and item_group.external_id == 28:
        frappe.db.set_value("Item", item.name, "disabled", 1)
        log_invalid_item(item)

    frappe.db.commit()

    return True
Beispiel #17
0
def sync_item(data):
	barcode = str(data.get("id"))
	remaining_quantity = flt(data.get("remaining_quantity"))
	name = None

	item_values = get_item_values(barcode, ["name", "transaction_id"])
	if item_values:
		name, transaction_id = item_values
		if not (frappe.flags.force_sync or False) and transaction_id == data.get("transactionid"):
			frappe.db.set_value("Item", name, "bio_last_sync", now(), update_modified=False)
			return False

	# inventory type
	item_group = find_item_group(data)
	warehouse = find_warehouse(data)
	current_remaining_quantity = 0

	# product (Item) mapping
	if data.get("productname"):
		item_name = data.get("productname")
	else:
		item_name = " ".join(filter(None, [data.get("strain"), item_group.name]))

	if not name:
		item_code = barcode
		item = frappe.get_doc({
			"doctype": "Item",
			"item_code": item_code,
			"item_name": item_name,
			"bio_barcode": barcode,
			"is_stock_item": 1,
			"stock_uom": "Gram",
			"item_group": item_group.name,
			"default_warehouse": warehouse.name,
		})
	else:
		item = frappe.get_doc("Item", name)
		current_remaining_quantity = item.bio_remaining_quantity

	strain = ""
	if data.get("strain"):
		strain = find_strain(data.get("strain"))

	# Post task will do on biotrack_after_sync hook
	parent_ids = data.get("parentid")
	plant_ids = data.get("plantid")
	if not item.is_lot_item and (parent_ids or plant_ids):
		item.set("linking_data", json.dumps({"parent_ids": parent_ids, "plant_ids": plant_ids}))

	item.update({
		"item_name": item_name,
		"bio_barcode": barcode,
		"strain": strain,
		"bio_remaining_quantity": remaining_quantity,
		"transaction_id": data.get("transactionid"),
		"bio_last_sync": now(),
		"disabled": 1 if remaining_quantity == 0 else 0,
	})

	item.flags.ignore_links = True
	item.save()

	# adjust_stock
	if item.is_stock_item:
		if remaining_quantity > current_remaining_quantity:
			make_stock_entry(item_code=item.name, target=item.default_warehouse, qty=remaining_quantity - current_remaining_quantity)

		# Consider to not modified down item's balance because it's hard to figure out the correct warehouse and its balance to deduct
		# elif remaining_quantity < current_remaining_quantity:
		# 	posting_date, posting_time = nowdate(), nowtime()
		# 	balance = get_stock_balance_for(item.name, item.default_warehouse, posting_date, posting_time)
		#
		# 	if balance["qty"] >= remaining_quantity:
		# 		make_stock_entry(item_code=item.name, source=item.default_warehouse,
		# 					 qty=current_remaining_quantity - remaining_quantity)

	# Disable Usable Marijuana item does not have product name
	if not data.get("productname") and item_group.external_id == 28:
		frappe.db.set_value("Item", item.name, "disabled", 1)
		log_invalid_item(item)

	frappe.db.commit()

	return True
Beispiel #18
0
def sync_plant(data):
    barcode = data.get("id")
    name = frappe.db.sql_list(
        "select name from tabPlant where name=%(barcode)s or bio_barcode=%(barcode)s",
        {"barcode": barcode})

    if name:
        name = name.pop()
        doc = frappe.get_doc("Plant", name)
        if doc.get("bio_transaction_id") == data.get("transactionid"):
            frappe.db.set_value("Plant",
                                name,
                                "bio_last_sync",
                                now(),
                                update_modified=False)
            return False
    else:
        sessiontime = datetime.datetime.fromtimestamp(
            cint(data.get("sessiontime")))
        doc = frappe.get_doc({
            "__islocal": 1,
            "doctype": "Plant",
            "bio_barcode": barcode,
            "posting_date": sessiontime.strftime(DATE_FORMAT),
            "posting_time": sessiontime.strftime(TIME_FORMAT)
        })

    plant_room = frappe.get_doc("Plant Room", {"bio_id": data.get("room")})
    doc.update({
        "strain": find_strain(data.get("strain")),
        "plant_room": plant_room.get("name") if plant_room else "",
        "is_mother_plant": cint(data.get("mother")),
        "destroy_scheduled": cint(data.get("removescheduled")),
        "harvest_collect": cint(data.get("harvestcollect")),
        "cure_collect": cint(data.get("curecollect")),
        "bio_transaction_id": cint(data.get("transactionid")),
        "bio_last_sync": now(),
        "disabled": 0,
    })

    item_values = get_item_values(data.get("parentid"), ["name", "item_group"])
    if item_values:
        item, item_group = item_values
        doc.item = item
        doc.item_group = item_group

    if doc.get("destroy_scheduled") and data.get("removescheduletime"):
        doc.remove_time = datetime.datetime.fromtimestamp(
            cint(data.get("removescheduletime"))).strftime(DATETIME_FORMAT)

        if data.get("removereason"):
            doc.remove_reason = data.get("removereason")

    state = cint(data.get("state"))
    doc.state = "Drying" if state == 1 else (
        "Cured" if state == 2 else "Growing")

    doc.flags.in_import = True
    doc.flags.ignore_validate_update_after_submit = True
    doc.flags.ignore_mandatory = True

    if doc.is_new():
        doc.submit()
    else:
        doc.save()

    frappe.db.commit()