Updated Links
This commit is contained in:
@@ -2,11 +2,13 @@ import frappe
|
||||
from functools import reduce
|
||||
from datetime import date
|
||||
|
||||
# frappe.utils.logger.set_log_level("DEBUG")
|
||||
# logger = frappe.logger("manufacturing_overview",
|
||||
# allow_site=True, file_count=100000)
|
||||
from erpnext.manufacturing.doctype.bom.bom import get_bom_items, BOM, get_bom_items_as_dict
|
||||
from erpnext.stock.get_item_details import get_default_bom
|
||||
|
||||
# logger.debug(f"String")
|
||||
frappe.utils.logger.set_log_level("DEBUG")
|
||||
logger = frappe.logger("manufacturing_overview", allow_site=True)
|
||||
|
||||
#logger.debug(f"String")
|
||||
|
||||
|
||||
def getDueInDays(d):
|
||||
@@ -14,9 +16,12 @@ def getDueInDays(d):
|
||||
return delta.days
|
||||
|
||||
|
||||
def getWorkOrders(soname):
|
||||
return frappe.get_all("Work Order", filters={
|
||||
'sales_order': soname}, fields=['name'])
|
||||
def getWorkOrder(soItemName):
|
||||
return frappe.get_all("Work Order", filters={"sales_order_item": soItemName})
|
||||
|
||||
def getPurchaseOrder(soItemName):
|
||||
|
||||
return frappe.get_all("Purchase Order Item", filters={"sales_order_item": soItemName}, fields=['parent'])
|
||||
|
||||
|
||||
def getAmountInWarehouses(item_code):
|
||||
@@ -64,6 +69,7 @@ def generateProductionOverviewCacheData():
|
||||
delivery_date, item_code, name
|
||||
""", as_dict=1)
|
||||
|
||||
|
||||
currentWarehouseQtyList = []
|
||||
|
||||
for soItem in salesOrderItems:
|
||||
@@ -77,6 +83,19 @@ def generateProductionOverviewCacheData():
|
||||
soItem.customer = shortenCustomerName(frappe.get_value(
|
||||
'Sales Order', soItem.parent, 'customer'))
|
||||
|
||||
soItem.direct_po = getPurchaseOrder(soItem.name)
|
||||
if len(soItem.direct_po) >= 1:
|
||||
soItem.direct_po = soItem.direct_po[0]['parent']
|
||||
else:
|
||||
soItem.direct_po = None
|
||||
soItem.direct_wo = getWorkOrder(soItem.name)
|
||||
if len(soItem.direct_wo) >= 1:
|
||||
soItem.direct_wo = soItem.direct_wo[0]['name']
|
||||
else:
|
||||
soItem.direct_wo = None
|
||||
|
||||
|
||||
|
||||
soItem = formatDate(soItem)
|
||||
soItem = calculateStatus(soItem)
|
||||
soItem.qty = soItem.qty - soItem.delivered_qty
|
||||
@@ -125,6 +144,36 @@ def getSalesorderOverviewList():
|
||||
|
||||
if salesOrderItems is None:
|
||||
salesOrderItems = generateProductionOverviewCacheData()
|
||||
frappe.cache().set_value('production_overview', salesOrderItems, expires_in_sec=60)
|
||||
frappe.cache().set_value('production_overview', salesOrderItems, expires_in_sec=1)
|
||||
|
||||
return salesOrderItems
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_bom_tree(item_code):
|
||||
bom_name = get_default_bom(item_code)
|
||||
root_bom = frappe.get_doc("BOM", bom_name)
|
||||
if root_bom != None:
|
||||
bom_tree = BOM.traverse_tree(root_bom) # Gets all BOM in correct order
|
||||
|
||||
bomlist = []
|
||||
|
||||
for bom_item in bom_tree:
|
||||
bom = frappe.get_doc("BOM", bom_item)
|
||||
bomlist.append(bom)
|
||||
# item = frappe.get_doc("Item", bom)
|
||||
|
||||
|
||||
# current_bom_item = frappe.get_doc("BOM", 'BOM-0815-3-001').get_tree_representation()
|
||||
# bom_items = get_bom_items("BOM-0815-3-001", "Hans Prothmann GmbH") #Fetches all raw materials
|
||||
|
||||
# routing = BOM.get_routing(frm) #Gets alls operations
|
||||
|
||||
# test = get_bom_items_as_dict(bom_name, "Hans Prothmann GmbH") # Gets all rm items as a dict
|
||||
|
||||
# bomtreeitem = BOM.get_tree_representation(bom_name)
|
||||
logger.debug(bomlist)
|
||||
|
||||
|
||||
|
||||
# logger.debug(bomtree)
|
||||
return bomlist
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
import frappe
|
||||
from erpnext.stock.get_item_details import get_default_bom
|
||||
from frappe.utils import (
|
||||
nowdate
|
||||
)
|
||||
|
||||
# frappe.utils.logger.set_log_level("DEBUG")
|
||||
# logger = frappe.logger("manufacturing_overview",
|
||||
# allow_site=True, file_count=50)
|
||||
frappe.utils.logger.set_log_level("DEBUG")
|
||||
logger = frappe.logger("manufacturing_overview",
|
||||
allow_site=True, file_count=50)
|
||||
# logger.debug(f"{wo_id}")
|
||||
|
||||
# logger.debug(f"{current_value} + {value} = {updated_value}")
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
@@ -57,3 +60,48 @@ def makepp(sales_order):
|
||||
|
||||
return {'status': 201,
|
||||
'docname': [pp.name]}
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def fixfinisheditemwopo(production_plan):
|
||||
pp = frappe.get_doc("Production Plan", production_plan)
|
||||
wo_id = frappe.get_all('Work Order', filters={'production_plan_item': pp.po_items[0].name})
|
||||
wo_id = wo_id[0]["name"]
|
||||
|
||||
frappe.delete_doc("Work Order", wo_id)
|
||||
|
||||
|
||||
po = frappe.new_doc("Purchase Order")
|
||||
po.supplier = pp.po_items[0].custom_supplier
|
||||
po.schedule_date = nowdate()
|
||||
po.is_subcontracted = 1
|
||||
|
||||
for row in pp.po_items:
|
||||
po_data = {
|
||||
"fg_item": row.item_code,
|
||||
# "warehouse": row.fg_warehouse,
|
||||
# "production_plan_sub_assembly_item": row.name,
|
||||
# "bom": row.bom_no,
|
||||
# "production_plan": pp.name,
|
||||
# "fg_item_qty": row.qty,
|
||||
}
|
||||
|
||||
# for field in [
|
||||
# "schedule_date",
|
||||
# "qty",
|
||||
# "description",
|
||||
# "production_plan_item",
|
||||
# ]:
|
||||
# po_data[field] = row.get(field)
|
||||
|
||||
po.append("items", po_data)
|
||||
|
||||
po.set_service_items_for_finished_goods()
|
||||
po.set_missing_values()
|
||||
po.flags.ignore_mandatory = True
|
||||
po.flags.ignore_validate = True
|
||||
po.insert()
|
||||
|
||||
|
||||
return {'status': 201,
|
||||
'docname': po.name}
|
||||
@@ -1,4 +1,5 @@
|
||||
import './manufacturing_overview_desk.vue';
|
||||
import './manufacturing_overview_page.js';
|
||||
import './manufacturing_overview_row.vue';
|
||||
import './production_plan.js';
|
||||
import './sales_order_addition.js';
|
||||
import './production_plan_addition.js';
|
||||
@@ -15,7 +15,8 @@
|
||||
<manufacturing-overview-row v-for="so in salesorderData" :key="so.name" v-bind:qty="so.qty"
|
||||
v-bind:item_name="so.item_name" v-bind:item_code="so.item_code" v-bind:customer="so.customer"
|
||||
v-bind:delivery_date="so.delivery_date" v-bind:status="so.status" v-bind:link="so.link"
|
||||
v-bind:reference="so.parent" v-bind:due_in="so.due_in">
|
||||
v-bind:reference="so.parent" v-bind:due_in="so.due_in" v-bind:direct_wo="so.direct_wo"
|
||||
v-bind:direct_po="so.direct_po">
|
||||
</manufacturing-overview-row>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,6 +44,8 @@ export default {
|
||||
sales_order: "",
|
||||
status: "Unknown",
|
||||
due_in: 0,
|
||||
direct_wo: "",
|
||||
direct_po: "",
|
||||
},
|
||||
],
|
||||
timer: "",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
<template>
|
||||
<div @click="pushRoute(link)" class="quick-list-item align-items-start">
|
||||
<div @click="pushRoute(link)" @mouseenter="hover = true" @mouseleave="hover = false, detailsOpen = false"
|
||||
class="quick-list-item align-items-start">
|
||||
<div class="col-1">
|
||||
<span class="indicator-pill no-margin" v-bind:class="{
|
||||
red: status === 'No Work Order',
|
||||
@@ -28,45 +29,92 @@
|
||||
</div>
|
||||
<div>
|
||||
<small>
|
||||
<span>
|
||||
<a class="underline-hover" @click="pushRoute('/app/sales-order/' + reference)" v-on:click.stop>{{
|
||||
reference
|
||||
}}</a>
|
||||
</span>
|
||||
<span v-if="direct_wo">
|
||||
-
|
||||
<a class="underline-hover" @click="pushRoute('/app/work-order/' + direct_wo)" v-on:click.stop>{{
|
||||
direct_wo
|
||||
}}</a>
|
||||
</span>
|
||||
<span v-if="direct_po">
|
||||
-
|
||||
<a class="underline-hover" @click="pushRoute('/app/purchase-order/' + direct_po)" v-on:click.stop>{{
|
||||
direct_po
|
||||
}}</a>
|
||||
</span>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="due_in < 0" class="text-muted ellipsis color-secondary col col-xs-3 text-right">
|
||||
<b style="color: red">{{ delivery_date }}</b>
|
||||
<!-- v-if="hover" -->
|
||||
|
||||
<div class="text-muted ellipsis color-secondary col col-xs-3 text-right">
|
||||
<div class="d-flex justify-content-end flex-column align-items-end">
|
||||
<div class="mb-auto">
|
||||
<b v-if="due_in < 0" style="color: red">{{ delivery_date }}</b>
|
||||
<b v-else-if="due_in === 0" style="color: black">{{ delivery_date }}</b>
|
||||
<span v-else>{{ delivery_date }}</span>
|
||||
</div>
|
||||
<div v-else-if="due_in === 0" class="text-muted ellipsis color-secondary col col-xs-3 text-right">
|
||||
<b style="color: black">{{ delivery_date }}</b>
|
||||
|
||||
<!-- <div @click="getItemDetails(item_code)" v-if="!detailsOpen" v-on:click.stop>
|
||||
Details
|
||||
</div> -->
|
||||
</div>
|
||||
<div v-else class="text-muted ellipsis color-secondary col col-xs-3 text-right">
|
||||
{{ delivery_date }}
|
||||
|
||||
|
||||
</div>
|
||||
<div v-if="detailsOpen" :style="{ height: '500px' }"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ManufacturingOverviewRow",
|
||||
data() {
|
||||
return {
|
||||
hover: false,
|
||||
detailsOpen: false,
|
||||
currentDetails: ['1', '2']
|
||||
};
|
||||
},
|
||||
props: [
|
||||
"qty",
|
||||
"item_name",
|
||||
"item_code",
|
||||
"customer",
|
||||
"customershort",
|
||||
"delivery_date",
|
||||
"status",
|
||||
"link",
|
||||
"reference",
|
||||
"due_in",
|
||||
"direct_wo",
|
||||
"direct_po",
|
||||
],
|
||||
methods: {
|
||||
pushRoute(link) {
|
||||
frappe.router.push_state(link);
|
||||
},
|
||||
getItemDetails(item) {
|
||||
this.detailsOpen = !this.detailsOpen
|
||||
frappe.call({
|
||||
method:
|
||||
"manufacturing_overview.manufacturing_overview.api.get_bom_tree",
|
||||
async: true,
|
||||
args: { item_code: item },
|
||||
callback: function (r) {
|
||||
console.log(r.message)
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
30
manufacturing_overview/public/js/production_plan_addition.js
Normal file
30
manufacturing_overview/public/js/production_plan_addition.js
Normal file
@@ -0,0 +1,30 @@
|
||||
frappe.ui.form.on("Production Plan", {
|
||||
refresh: function (frm) {
|
||||
frm.add_custom_button(__('Fix WO/PO'), function () {
|
||||
frappe.call({
|
||||
method: 'manufacturing_overview.manufacturing_overview.productionplan.fixfinisheditemwopo',
|
||||
args: {
|
||||
production_plan: frm.docname
|
||||
},
|
||||
callback: function (r) {
|
||||
if (r.message.status === 201) {
|
||||
frappe.msgprint({
|
||||
title: __('Created'),
|
||||
indicator: 'green',
|
||||
message: __('Purchase Order {0} created.',
|
||||
['<a href="/app/purchase-order/' + r.message.docname + '">' + r.message.docname + '</a>'])
|
||||
});
|
||||
} else if (r.message.status === 400) {
|
||||
frappe.msgprint({
|
||||
title: __('Already exists'),
|
||||
indicator: 'yellow',
|
||||
message: "Oooopsie"
|
||||
});
|
||||
} else {
|
||||
console.log(r.message)
|
||||
}
|
||||
}
|
||||
});
|
||||
})
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user