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
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()
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()
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})
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"})
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)
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()
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()
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)
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)
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()
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
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
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
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()