class ModifyStuffParmeter(QDialog, Ui_Dialog): def __init__(self, autoid, parent=None): super(ModifyStuffParmeter, self).__init__(parent) self.ori_detail = dict() self.detail = {} self.new_detail = dict() self.WC = WarehouseController() self.SFC = StuffController() self.setupUi(self) self.autoid = autoid self.get_detail() self.set_validator() self.get_location_list() def get_detail(self): if not self.autoid: self.pushButton_accept.setEnabled(False) return key_dict = { 'autoid': self.autoid } res = self.WC.get_stuffrepository( False, *VALUES_TUPLE_STUFF, **key_dict ) if len(res) != 1: return self.ori_detail = res[0] self.lineEdit_content.setText(str(self.ori_detail['content'])) self.label_contentunit.setText(self.ori_detail['cunit']) self.lineEdit_water.setText(str(self.ori_detail['water'])) self.lineEdit_rdensity.setText(str(self.ori_detail['rdensity'])) self.lineEdit_impurity.setText(str(self.ori_detail['impurity'])) def set_validator(self): doubleValitor = QDoubleValidator() doubleValitor.setBottom(-1) doubleValitor.setDecimals(3) doubleValitor.setNotation(QDoubleValidator.StandardNotation) self.lineEdit_content.setValidator(doubleValitor) self.lineEdit_water.setValidator(doubleValitor) self.lineEdit_rdensity.setValidator(doubleValitor) self.lineEdit_impurity.setValidator(doubleValitor) def get_location_list(self): location_list = self.WC.get_stuffrepository( True, *VALUES_TUPLE_LOCATION).distinct() if len(location_list): self.comboBox_location.addItems(location_list) if len(self.ori_detail): self.comboBox_location.setCurrentText(self.ori_detail['position']) else: self.comboBox_location.setCurrentText("") @pyqtSlot(str) def on_lineEdit_content_textChanged(self, p_str): if p_str != '': p_str = decimal.Decimal(p_str) else: p_str = decimal.Decimal(-1) try: if p_str != self.ori_detail['content']: self.new_detail['content'] = p_str else: try: del self.new_detail['content'] except KeyError: pass except KeyError: self.new_detail['content'] = p_str @pyqtSlot(str) def on_lineEdit_water_textChanged(self, p_str): if p_str != '': p_str = decimal.Decimal(p_str) else: p_str = decimal.Decimal(p_str) try: if p_str != self.ori_detail['water']: self.new_detail['water'] = p_str else: try: del self.new_detail['water'] except KeyError: pass except KeyError: self.new_detail['water'] = p_str @pyqtSlot(str) def on_lineEdit_rdensity_textChanged(self, p_str): if p_str != '': p_str = decimal.Decimal(p_str) else: p_str = decimal.Decimal(p_str) try: if p_str != self.ori_detail['rdensity']: self.new_detail['rdensity'] = p_str else: try: del self.new_detail['rdensity'] except KeyError: pass except KeyError: self.new_detail['rdensity'] = p_str @pyqtSlot(str) def on_lineEdit_impurity_textChanged(self, p_str): if p_str != '': p_str = decimal.Decimal(p_str) else: p_str = decimal.Decimal(p_str) try: if p_str != self.ori_detail['impurity']: self.new_detail['impurity'] = p_str else: try: del self.new_detail['impurity'] except KeyError: pass except KeyError: self.new_detail['impurity'] = p_str @pyqtSlot(str) def on_comboBox_location_currentTextChanged(self, p_str): try: if p_str != self.ori_detail['position']: self.new_detail['position'] = p_str else: try: del self.new_detail['position'] except KeyError: pass except KeyError: self.new_detail['position'] = p_str @pyqtSlot() def on_pushButton_accept_clicked(self): if len(self.new_detail): self.WC.update_stuffrepository(self.autoid, **self.new_detail) self.accept() @pyqtSlot() def on_pushButton_cancel_clicked(self): self.close()
class StuffRepositoryModule(QWidget, Ui_Form): def __init__(self, parent=None): super(StuffRepositoryModule, self).__init__(parent) self.setupUi(self) if '41' not in user.powers: self.close() if user.powers['41'] == 0: self.close() self.power = '{:03b}'.format(user.powers['41']) self.WC = WarehouseController() self.CI = CheckItem() self.LC = LabrecordsController() self.SFC = StuffController() self.current_button = self.radioButton_batchno self.get_stuff_list() def get_stuff_list(self): if self.current_button == self.radioButton_batchno: values_tuple = VALUES_TUPLE_BATCHNO self.treeWidget_stuffbatchnolist.setVisible(True) self.treeWidget_stuffkindlist.setVisible(False) current_tree = self.treeWidget_stuffbatchnolist current_tree.hideColumn(0) current_tree.hideColumn(1) elif self.current_button == self.radioButton_kind: values_tuple = VALUES_TUPLE_KIND self.treeWidget_stuffbatchnolist.setVisible(False) self.treeWidget_stuffkindlist.setVisible(True) current_tree = self.treeWidget_stuffkindlist else: return current_tree.clear() index = self.tabWidget.currentIndex() key_dict = {'amount__gt': 0} if index != 0: key_dict['stufftype'] = index - 1 stuff_list = self.WC.get_stuffrepository(False, *values_tuple, **key_dict) if not len(stuff_list): return if current_tree == self.treeWidget_stuffbatchnolist: self.set_batchno_tree(current_tree, stuff_list) for i in range(2, 25): current_tree.resizeColumnToContents(i) elif current_tree == self.treeWidget_stuffkindlist: self.set_kind_tree(current_tree, stuff_list) for i in range(0, 3): current_tree.resizeColumnToContents(i) else: return def set_batchno_tree(self, current_tree, stuff_list): for item in stuff_list: qtreeitem = QTreeWidgetItem(current_tree) qtreeitem.setText(0, str(item['autoid'])) qtreeitem.setText(1, str(item['lrid'])) qtreeitem.setText(2, STATUS[item['status']]) qtreeitem.setText(3, item['stuffid'] + ' ' + item['stuffname']) qtreeitem.setText(4, item['stuffkind']) qtreeitem.setText(5, STUFF_KIND[item['stufftype']]) qtreeitem.setText(6, item['batchno']) qtreeitem.setText(7, item['mbatchno']) qtreeitem.setText(8, item['spec']) qtreeitem.setText(9, item['package']) qtreeitem.setText(10, str(item['piamount'])) qtreeitem.setText(11, str(item['amount'])) qtreeitem.setText(12, item['basicunit']) qtreeitem.setText(13, item['position']) qtreeitem.setText(14, str(item['makedate'])) qtreeitem.setText(15, str(item['putindate'])) qtreeitem.setText(16, str(item['expireddate'])) qtreeitem.setText(17, str(item['nextcheckdate'])) qtreeitem.setText(18, item['supid'] + ' ' + item['supname']) qtreeitem.setText(19, item['producer']) qtreeitem.setText(20, str(item['content']) + item['cunit']) qtreeitem.setText(21, str(item['water']) + '%') qtreeitem.setText(22, str(item['rdensity'])) qtreeitem.setText(23, str(item['impurity']) + '%') qtreeitem.setText( 24, item['warehousemanid'] + item['warehousemanname']) def set_kind_tree(self, current_tree, stuff_list): kind_list = stuff_list.annotate(amount=Sum('amount'), piamount=Sum('piamount')) for item in kind_list: qtreeitem = QTreeWidgetItem(current_tree) qtreeitem.setText(0, item['stuffkind']) qtreeitem.setText(1, str(item['piamount'])) qtreeitem.setText(2, str(item['amount'])) qtreeitem.setText(3, item['basicunit']) @pyqtSlot(int) def on_tabWidget_currentChanged(self, p_int): curent_tab = getattr(self, 'tab_' + str(p_int)) curent_tab.setLayout(self.gridLayout_2) self.get_stuff_list() pyqtSlot(bool) def on_radioButton_batchno_toggled(self, p_bool): if p_bool: self.current_button = self.radioButton_batchno self.get_stuff_list() pyqtSlot(bool) def on_radioButton_kind_toggled(self, p_bool): if p_bool: self.current_button = self.radioButton_kind self.get_stuff_list() @pyqtSlot(QPoint) def on_treeWidget_stuffbatchnolist_customContextMenuRequested(self, pos): if self.power[1] == '0': return id = 0 lrid = 0 stuffid = '' batchno = '' sender_widget = self.sender() current_item = sender_widget.currentItem() if current_item is None: return id = int(current_item.text(0)) lrid = int(current_item.text(1)) stuffid, stuffname = current_item.text(3).split(' ') batchno = current_item.text(6) menu = QMenu() button1 = menu.addAction("修改记录") button2 = menu.addAction("查看检验报告") button3 = menu.addAction("新建库存复检申请单") global_pos = sender_widget.mapToGlobal(pos) action = menu.exec(global_pos) if action == button1: detail = ModifyStuffParmeter(id, self) detail.accepted.connect(self.get_stuff_list) detail.show() elif action == button2: detail = FindCheckReportModule(stuffid, batchno, self) detail.show() elif action == button3: key_dict = {'stuffid': stuffid, 'stuffname': stuffname} checkunit = '' res = self.SFC.get_stuffdict(True, *VALUES_TUPLE_SD, **key_dict) if len(res): checkunit = res[0] kwargs = { 'labtype': 1, 'chkid': stuffid, 'chkname': stuffname, 'batchno': current_item.text(6), 'mbatchno': current_item.text(7), 'spec': current_item.text(8), 'package': current_item.text(9), 'producer': current_item.text(19), 'supplyer': current_item.text(18) if current_item.text(18) in ('', ' ') else current_item.text(18).split(' ')[2], 'ciid': int(current_item.text(0)), 'createdate': user.now_date, 'checkamount': decimal.Decimal(current_item.text(11)), 'caunit': current_item.text(12), 'sampleunit': checkunit, 'samplesource': current_item.text(13) } labrecord = self.LC.update_labrecord(**kwargs) key_dict_checkitem = {'stuffid': stuffid, 'itemtype': 0} checkitems = self.CI.get_checkitems(False, *VALUES_TUPLE_CHECKITEM, **key_dict_checkitem) for item in checkitems: kwargs_checkitem = { 'lrid': labrecord.autoid, 'seqid': item['seqid'], 'itemname': item['itemname'], 'kind': item['kind'], 'referencevalue': item['referencevalue'], 'labvalue': item['referencevalue'], 'putintype': item['putintype'], 'startdate': user.now_date, 'enddate': user.now_date, 'checked': 2 } self.LC.update_labitem(**kwargs_checkitem) detail = ApplycheckModule(autoid=labrecord.autoid, parent=self) detail.rejected.connect( lambda: self.delete_check_report(labrecord.autoid)) detail.show() def delete_check_report(self, lrid): self.LC.delete_labrecord(lrid) self.LC.delete_labitem(lrid) @pyqtSlot(QTreeWidgetItem, int) def on_treeWidget_stuffbatchnolist_itemDoubleClicked( self, qtreeitem, p_int): if self.power[1] == '0': return id = int(qtreeitem.text(0)) lrid = int(qtreeitem.text(1)) detail = ModifyStuffParmeter(id, self) detail.accepted.connect(self.get_stuff_list) detail.show()
class DrawstuffModule(QDialog, Ui_Dialog): def __init__(self, ppid, sdpid, kind, parent=None): super(DrawstuffModule, self).__init__(parent) self.ppid = ppid self.sdpid = sdpid self.kind = kind self.setupUi(self) if '37' not in user.powers: self.close() if user.powers['37'] == 0: self.close() self.power = '{:03b}'.format(user.powers['37']) if self.power[1] == '0': self.pushButton_accept.setVisible(False) self.pushButton_cancel.setVisible(False) self.WC = WarehouseController() self.SC = StuffController() self.PC = ProductController() self.PLC = ProductLineConroller() self.detail = dict() self.stuff_list = [] # 当前正在修改的树节点 self.edittreeitem = None self.stuff_repository = [] # 公式错误信息 self.errormsg = [] self.treeWidget_stuffrepository.setDragDropMode(1) self.treeWidget_drawstuff.setDragDropMode(2) def showMaximized(self): try: #获取产品信息 self.get_product_detail() self.get_formula() self.get_has_drawstuff(self.ppid) self.draw_stuff() # 配方有错误信息,提示错误内容 if len(self.errormsg): self.pushButton_accept.setEnabled(False) self.show_errormsg(self.errormsg) super(DrawstuffModule, self).showMaximized() except Exception as e: self.done(6) # 显示错误信息 def show_errormsg(self, msg): text = "以下物料配方设置出错,请检查配方后重新领料" informative = "" for i, item in enumerate(msg): informative += str(i + 1) + '、' + item + '设置出错\n' dialog = MessageBox(self, text=text, informative=informative) dialog.show() # 获取当前领料单的物料配方 def get_formula(self): if self.detail['pltype'] == 0: table = ['Productdictionary'] condition = [ 'Productdictionary.autoid=Productprescription.prodid', 'Productdictionary.prodid=' + self.detail['prodid'] ] else: table = ['Stuffdictionary'] condition = [ 'Stuffdictionary.autoid=Productprescription.prodid', 'Stuffdictionary.stuffid=' + self.detail['prodid'] ] # 获得配方 if self.kind == 0: res = self.PLC.get_formula(version=self.detail['version'], stufftype__in=(0, 1, 2), prodtype=self.detail['pltype']).extra( tables=table, where=condition) else: res = self.PLC.get_formula(version=self.detail['version'], stufftype=self.kind + 2, prodtype=self.detail['pltype']).extra( tables=table, where=condition) stuffkind_list = [] if len(res): # 显示配方 for item in res: qtreeitem = QTreeWidgetItem(self.treeWidget_formula) qtreeitem.setText(1, STUFFTYPE[item.stufftype]) qtreeitem.setText(2, item.stuffkind) qtreeitem.setText(3, item.formula) qtreeitem.setText(4, item.presexpression) qtreeitem.setText(5, item.pracexpression) qtreeitem.setText(6, item.drawexpression) # 领料精度 qtreeitem.setText(7, str(item.precision)) # 损耗限度 qtreeitem.setText(8, str(item.loss)) # 标记该物料是否已经发够料 qtreeitem.setText(9, '0') stuffkind_list.append(item.stuffkind) self.treeWidget_formula.hideColumns(0, 4, 5, 6, 7, 8, 9) self.treeWidget_formula.resizeColumns(300, 1, 2, 3) # 如果当前配方不为空,则获取对应的库存 if len(stuffkind_list): self.get_stuffrep_gt_zero(stuffkind_list) # 获取本批产品其他领料单已经领取了的物料 def get_has_drawstuff(self, ppid): values_tupe = ("autoid", "stuffid", "stuffname", "stuffkind", "spec", "package", "presamount", "pracamount", "drawamount", "content", "water", "impurity", "rdensity") stuffs = self.SC.get_prodstuff(0, ppid=ppid, *values_tupe) if len(stuffs): self.stuff_list_additem(stuffs) # 把领取的物料加到领料记录中,如果发现重复的情况则替换旧的记录 def stuff_list_additem(self, newitems): for newitem in newitems: flat = 0 for item in self.stuff_list: if newitem['autoid'] == item['autoid']: item = newitem flat = 1 if flat == 0: self.stuff_list.append(newitem) # 获取配方对应的物料 def get_stuffrep_gt_zero(self, stuffkind_list): self.treeWidget_stuffrepository.clear() row_tuple = ('autoid', 'stuffkind', 'stuffid', 'stuffname', 'spec', 'package', 'batchno', 'mbatchno', 'amount', 'producer', 'supid', 'supname', 'content', 'cunit', 'water', 'rdensity', 'impurity', 'basicunit', 'lrid', 'stufftype') res = self.WC.get_stuffrepository(False, *row_tuple, stuffkind__in=stuffkind_list, amount__gt=0) self.stuff_repository = res if len(res): for item in res: qtreeitem = QTreeWidgetItem(self.treeWidget_stuffrepository) qtreeitem.setText(0, str(item['autoid'])) qtreeitem.setText(1, str(item['stuffkind'])) qtreeitem.setText(2, item['stuffid'] + ' ' + item['stuffname']) qtreeitem.setText(3, item['spec']) qtreeitem.setText(4, item['package']) qtreeitem.setText(5, item['batchno']) qtreeitem.setText(6, item['mbatchno']) qtreeitem.setText(7, str(item['amount']) + item['basicunit']) qtreeitem.setText(9, item['supid'] + ' ' + item['supname']) qtreeitem.setText(10, item['producer']) qtreeitem.setText(11, str(item['content']) + item['cunit']) qtreeitem.setText(12, str(item['water']) + '%') qtreeitem.setText(13, str(item['rdensity'])) qtreeitem.setText(14, str(item['impurity'])) self.treeWidget_stuffrepository.hideColumns(0, 1, 15) column_list = [i for i in range(2, 15)] self.treeWidget_stuffrepository.resizeColumns(120, *column_list) # 获取产品信息 def get_product_detail(self): vlist = ('prodid', 'version', 'planamount', 'realamount', 'spec', 'basicamount', 'spamount', 'bpamount', 'bpamount', 'pltype') res = self.PC.get_producingplan(False, *vlist, autoid=self.ppid) self.detail = res[0] # 系统根据配方自动领料 def draw_stuff(self): it = QTreeWidgetItemIterator(self.treeWidget_formula) while it.value(): item = it.value() # 标记为0的列即为未领够料的记录 if item.text(9) == '0': stuffkind = item.text(2) precision = int(item.text(7)) loss = item.text(8) # 处理产品信息的变量,去除系统变量 item.setText(4, self.reckon_expression(item.text(4), 1)) # 计划量 try: presamount = Decimal( rnd(eval(item.text(4), evalenv(self)), precision)) except SyntaxError: if stuffkind + ' 计划量' not in self.errormsg: self.errormsg.append(stuffkind + ' 计划量') presamount = 0 # 把计划量加到产品信息变量中 # self.detail['presamount'] = presamount # 实际量公式,去除系统变量 item.setText(5, self.reckon_expression(item.text(5), 1)) # 领取量公式,去除系统变量 item.setText(6, self.reckon_expression(item.text(6), 1)) # 计算领料量,返回领料情况res, 和标记:是否已经领购料 res = self.reckon_drawamount(stuffkind, presamount, precision, item.text(5), item.text(6), loss) if len(res): self.treeWidget_drawstuff_add_item(res) it += 1 self.is_drawamount_enough() # 把计算结果存到领料树中 def treeWidget_drawstuff_add_item(self, items: dict): try: self.stuff_list_additem(items) for item in items: qtreeitem = QTreeWidgetItem(self.treeWidget_drawstuff) qtreeitem.setText(0, str(item['autoid'])) qtreeitem.setText(1, str(item['stuffkind'])) qtreeitem.setText(2, item['stuffid'] + ' ' + item['stuffname']) qtreeitem.setText(3, item['spec']) qtreeitem.setText(4, item['package']) qtreeitem.setText(5, str(item['oripresamount'])) qtreeitem.setText(6, item['basicunit']) qtreeitem.setText(7, str(item['newpracamount'])) qtreeitem.setText(8, item['basicunit']) qtreeitem.setText(9, str(item['drawamount'])) qtreeitem.setText(10, item['basicunit']) qtreeitem.setText(11, item['batchno']) qtreeitem.setText(12, item['mbatchno']) qtreeitem.setText(13, str(item['content']) + item['cunit']) qtreeitem.setText(14, str(item['water']) + '%') qtreeitem.setText(15, str(item['rdensity'])) qtreeitem.setText(16, str(item['impurity'])) qtreeitem.setText(17, str(item['loss'])) qtreeitem.setText(18, item['supid'] + ' ' + item['supname']) qtreeitem.setText(19, item['producer']) qtreeitem.setText(20, str(item['presamount'])) qtreeitem.setText(21, str(item['pracamount'])) qtreeitem.setText(22, str(item['precision'])) self.treeWidget_drawstuff.hideColumns(0, 1, 20, 21, 22) columns_list = [i for i in range(2, 20)] self.treeWidget_drawstuff.resizeColumns(200, *columns_list) except KeyError: pass # 计算系统变量 def reckon_expression(self, expression, iterdepth): # iterdepth:迭代深度,超过50则抛出RuntimeError # 产品信息变量,ex: @planamount@, @spec@, @package@ if iterdepth > 50: raise RuntimeError pattern = re.findall(r'@[%?!()()::.#\w]*@', expression) for item in pattern: if len(item[1:-1].split('.')) == 2: var_name, var_item = item[1:-1].split('.') value = Decimal('0') # 标记是否找到了对应的物料 find_stuff_flag = 0 for stuff in self.stuff_list: if stuff['stuffkind'] == var_name: find_stuff_flag = 1 if var_item == '计划量': value = stuff[VAR_ITEM[var_item]] expression = expression.replace(item, str(value)) break else: value += stuff[VAR_ITEM[var_item]] expression = expression.replace(item, str(value)) # 没有找到对应的物料则再本领料单中继续寻找 if find_stuff_flag == 0: formula_item = self.get_treeitem(self.treeWidget_formula) while 1: try: treeitem = next(formula_item) if treeitem.text(2) == var_name: if treeitem.text(9) == '0': # stuffkind = item.text(2) precision = int(treeitem.text(7)) loss = treeitem.text(8) # 处理产品信息的变量,去除系统变量 treeitem.setText( 4, self.reckon_expression( treeitem.text(4), iterdepth + 1)) # 计划量 try: presamount = Decimal( rnd( eval(treeitem.text(4), evalenv(self)), precision)) except SyntaxError: if var_name + ' 计划量' not in self.errormsg: self.errormsg.append(var_name + ' 计划量') presamount = 0 # 把计划量加到产品信息变量中 # self.detail['presamount'] = presamount # 实际量公式,去除系统变量 treeitem.setText( 5, self.reckon_expression( treeitem.text(5), iterdepth + 1)) # 领取量公式,去除系统变量 treeitem.setText( 6, self.reckon_expression( treeitem.text(6), iterdepth + 1)) # 计算领料量,返回领料情况res, 和标记:是否已经领购料 res = self.reckon_drawamount( var_name, presamount, precision, treeitem.text(5), treeitem.text(6), loss) if len(res): self.treeWidget_drawstuff_add_item(res) self.is_drawamount_enough() expression = self.reckon_expression( expression, iterdepth + 1) except (StopIteration, RuntimeError) as e: break else: key = item.replace('@', '') if key in self.detail: expression = expression.replace(item, str(self.detail[key])) #pattern_1 = re.findall(r'@[%?!()()::.#\w]*@', expression) return expression # 计算实际量 def reckon_pracamount(self, autoid, presamount, precision, expression): # stuffkind: 物料种类 # presamount: 计划量 # expression: 实际量的公式 stuff_detail = [] # 最终要领取的批次和实际量 # 分析公式,获取变量 pattern = re.findall(r'@\w*@', expression) # 把变量设置为对应的值 for item in self.stuff_repository: if autoid != item['autoid']: continue for key in pattern: k = key.replace('@', '') if k == 'presamount': expression = expression.replace(key, str(presamount)) elif k in item: expression = expression.replace(key, str(item[k])) elif k in self.detail: expression = expression.replace(key, str(self.detail[k])) try: pracamount = Decimal( rnd(eval(expression, evalenv(self)), precision)) except SyntaxError: if item['stuffkind'] + ' 实际量' not in self.errormsg: self.errormsg.append(item['stuffkind'] + ' 实际量') pracamount = 0 item['pracamount'] = pracamount # 计算领取量 def reckon_drawamount(self, stuffkindorsrid, presamount, precision, prac_expression, draw_expression, loss=0, flat=True): # stuffkindorsrid: 根据flat决定类型, True是物料种类,False是srid # presamount: 计划量 # precision: 计算结果精度 # prac_expression: 实际量公式 # draw_expression: 领取公式 # loss: 损耗限度 # flat: 是否需要继续领下一批物料,默认为True即继续领下一批物料, # False则不再领取下一批物料 # 要领取的物料批次 draw_list = [] # 已经领取了的量 has_drawamount = 0 # 分析公式,获取变量 pattern = re.findall(r'@\w*@', draw_expression) # 把变量设置为对应的值 for item in self.stuff_repository: item['oripresamount'] = presamount new_expression = draw_expression if has_drawamount != 0: presamount -= has_drawamount has_drawamount = 0 if stuffkindorsrid != (item['stuffkind'] if flat else str(item['autoid'])): continue has_draw_stuff = self.get_treeitem(self.treeWidget_drawstuff) # 检查该批次是否已经选择过了 draw_flag = 0 while 1: try: stuff = next(has_draw_stuff) if int(stuff.text(0)) == item['autoid']: draw_flag = 1 break except StopIteration: break if draw_flag == 1: continue item['loss'] = loss item['presamount'] = presamount item['precision'] = precision # 算出该批次对应的实际量 self.reckon_pracamount(item['autoid'], presamount, precision, prac_expression) for key in pattern: k = key.replace('@', '') if k in item: new_expression = new_expression.replace(key, str(item[k])) elif k in self.detail: new_expression = new_expression.replace( key, str(self.detail[k])) try: drawamount = Decimal( rnd(eval(new_expression, evalenv(self)), precision)) except SyntaxError: if stuffkindorsrid + ' 领取量' not in self.errormsg: self.errormsg.append(stuffkindorsrid + ' 领取量') drawamount = 0 if drawamount == 0: continue elif item['amount'] >= drawamount: item['drawamount'] = drawamount item['newpracamount'] = item['pracamount'] draw_list.append(item) break else: # 转化为计划量 = 领取量 * 计划量 / 实际量 has_drawamount = Decimal( rnd(item['amount'] * presamount / item['pracamount'], precision)) item['newpracamount'] = rnd(item['amount'], precision) item['drawamount'] = rnd(item['amount'], precision) draw_list.append(item) if not flat: # 指定库存记录时,默认按领够料处理 break return draw_list # 配方点击功能,选择一个物料种类后库存列表中只显示该物料 @pyqtSlot(QTreeWidgetItem, int) def on_treeWidget_formula_itemClicked(self, qtreeitem, p_int): stuffkind_list = [qtreeitem.text(2)] self.get_stuffrep_gt_zero(stuffkind_list) # 拖动库存记录到领料表 @pyqtSlot(QDropEvent, QPoint) def on_treeWidget_drawstuff_droped(self, event, pos): try: data = event.mimeData().data( 'application/x-qabstractitemmodeldatalist') data_items = decode_data(data) p_str = data_items[0][0] srid = int(p_str) # 如果该批次物料已经有领料记录则不做任何操作 if self.has_drawstuff(p_str): return stuff = dict() for item in self.stuff_repository: if srid == item['autoid']: stuff = item break if stuff is None: raise KeyError stuffkind = stuff['stuffkind'] it_formula = self.get_treeitem(self.treeWidget_formula) while 1: try: treeitem = next(it_formula) if treeitem.text(2) == stuffkind: planamount_expression = treeitem.text(4) pracamount_expression = treeitem.text(5) drawamount_expression = treeitem.text(6) precision = int(treeitem.text(7)) loss = treeitem.text(8) try: presamount = Decimal( rnd(eval(planamount_expression, evalenv(self)), precision)) except SyntaxError: if stuffkind + ' 计划量' not in self.errormsg: self.errormsg.append(stuffkind + ' 计划量') presamount = 0 # 没有领够料,继续拖新的物料批次 if treeitem.text(9) == '0': # 获取出该物料其他批次的实际领取量 it_drawstuff = self.get_treeitem( self.treeWidget_drawstuff) try: new_presamount = presamount while 1: drawitem = next(it_drawstuff) if drawitem.text(1) != stuffkind: continue # 转化为计划量 = 领取量 * 计划量 / 实际量 has_drawamount = rnd( Decimal(drawitem.text(9)) * Decimal(drawitem.text(20)) / Decimal(drawitem.text(21)), int(drawitem.text(22))) new_presamount -= has_drawamount except StopIteration: pass # 计算本批的领取量 res = self.reckon_drawamount( p_str, new_presamount, precision, pracamount_expression, drawamount_expression, loss, False) # 已经领够料,还继续拖新的物料批次 elif treeitem.text(9) == '1': res = self.reckon_drawamount( p_str, presamount, precision, pracamount_expression, drawamount_expression, loss, False) if len(res): res[0]['oripresamount'] = presamount self.treeWidget_drawstuff_add_item(res) self.is_drawamount_enough() break except StopIteration: break except ValueError: SaveExcept(ValueError, "拖动库存信息时出错,传入的不是srid", p_str, self.stuff_repository) except KeyError: SaveExcept(ValueError, "拖动库存信息时出错,没有找到对应的库存记录,", p_str, self.stuff_repository) # 领够料的物料自动设置成绿色,不够料的物料设置成黄色 @pyqtSlot(QTreeWidgetItem, int) def on_treeWidget_formula_itemChanged(self, qtreeitem, p_int): if p_int == 9: brush = QBrush(1) if qtreeitem.text(9) == '1': brush.setColor(QColor(85, 255, 127)) else: brush.setColor(QColor(255, 255, 127)) for i in range(1, 4): qtreeitem.setBackground(i, brush) @pyqtSlot(QTreeWidgetItem, int) def on_treeWidget_drawstuff_itemDoubleClicked(self, qtreeitem, p_int): try: srid = int(qtreeitem.text(0)) srdetail = dict() for item in self.stuff_repository: if item['autoid'] == srid: srdetail = item break dialog = ModifyDrawamountModule(srdetail, self) self.edittreeitem = qtreeitem dialog.modified.connect(self.setdrawamount) dialog.exec() except ValueError: pass # 把领料量设置为新的值 def setdrawamount(self, q_decimal): stuffkind = '' self.edittreeitem.setText(9, str(q_decimal)) self.edittreeitem.setText(7, str(q_decimal)) srid = int(self.edittreeitem.text(0)) for item in self.stuff_repository: if item['autoid'] == srid: item['pracamount'] = q_decimal item['drawamount'] = q_decimal stuffkind = item['stuffkind'] break self.is_drawamount_enough() self.edittreeitem = None # 判断领取的物料是否足够 def is_drawamount_enough(self): formula_treeitem = self.get_treeitem(self.treeWidget_formula) while 1: presamount = Decimal('0') try: fitem = next(formula_treeitem) precision = int(fitem.text(7)) presamount = Decimal( rnd(eval(fitem.text(4), evalenv(self)), precision)) stuffkind = fitem.text(2) drawstuff_treeitem = self.get_treeitem( self.treeWidget_drawstuff) while 1: try: ditem = next(drawstuff_treeitem) if ditem.text(1) != stuffkind: continue this_presamount = rnd( Decimal(ditem.text(7)) * Decimal(ditem.text(20)) / Decimal(ditem.text(21)), precision) presamount -= this_presamount except StopIteration: break if presamount > 0: fitem.setText(9, '0') else: fitem.setText(9, '1') except StopIteration: break except SyntaxError: continue # 删除已经选择好了的物料 @pyqtSlot(QPoint) def on_treeWidget_drawstuff_customContextMenuRequested(self, pos): if self.power[1] == '0': return sender_widget = self.sender() menu = QMenu() button1 = menu.addAction("删除该批次物料") button2 = menu.addAction("修改领取量") global_pos = sender_widget.mapToGlobal(pos) action = menu.exec(global_pos) # 删除该批次物料 if action == button1: try: self.delete_drawstuff(sender_widget.selectedItems()) except AttributeError: pass # 修改领取量 elif action == button2: try: self.modify_drawstuff(sender_widget.currentItem()) except AttributeError: pass # 判断物料是否已经有领取记录 def has_drawstuff(self, p_str): itemiter = self.get_treeitem(self.treeWidget_drawstuff) flag = False while 1: try: treeitem = next(itemiter) if p_str == treeitem.text(0): flag = True break except StopIteration: break return flag # 删除待领取的物料 def delete_drawstuff(self, qtreeitems): # qtreeitems: 选中的项目 if len(qtreeitems): it = QTreeWidgetItemIterator(self.treeWidget_formula) root = self.treeWidget_drawstuff.invisibleRootItem() for item in qtreeitems: root.removeChild(item) self.is_drawamount_enough() def get_treeitem(self, qtreewidget): it = QTreeWidgetItemIterator(qtreewidget) while it.value(): yield it.value() it += 1 @pyqtSlot() def on_pushButton_accept_clicked(self): it = QTreeWidgetItemIterator(self.treeWidget_drawstuff) draw_list = [] key_list = ['srid', 'stuffkind'] while it.value(): treeitem = it.value() item = self.qtreeitem2dict(key_list, treeitem) for stuff in self.stuff_repository: if stuff['autoid'] == int(item['srid']): item['stuffid'] = stuff['stuffid'] item['stuffname'] = stuff['stuffname'] item['stufftype'] = stuff['stufftype'] item['stuffkind'] = stuff['stuffkind'] item['spec'] = stuff['spec'] item['package'] = stuff['package'] item['producer'] = stuff['producer'] item['batchno'] = stuff['batchno'] item['lrid'] = stuff['lrid'] item['content'] = stuff['content'] item['cunit'] = stuff['cunit'] item['water'] = stuff['water'] item['impurity'] = stuff['impurity'] item['rdensity'] = stuff['rdensity'] item['mbatchno'] = stuff['mbatchno'] break item['sdpid'] = self.sdpid item['ppid'] = self.ppid draw_list.append(item) it += 1 sdpid_list = { 'autoid': self.sdpid, 'status': 2, 'providerid': user.user_id, 'providername': user.user_name, 'drawdate': user.now_date } res = self.WC.update_stuffrepository_amount(self.ppid, *draw_list, **sdpid_list) if res == 'accept': self.accept() elif res == 'rollback': msg = MessageBox(parent=self, text="领料信息异常!", informative="请刷新后重试!") msg.exec() timer = QTimer(self) timer.start(1000) timer.timeout.connect(msg.close) def qtreeitem2dict(self, key_list: list, q_treeitem: QTreeWidgetItem): q_dict = dict() q_dict['srid'] = q_treeitem.text(0) q_dict['presamount'] = Decimal(q_treeitem.text(5)) q_dict['checkamount'] = Decimal(q_treeitem.text(5)) q_dict['presunit'] = q_treeitem.text(6) q_dict['pracamount'] = Decimal(q_treeitem.text(7)) q_dict['pracunit'] = q_treeitem.text(8) q_dict['drawamount'] = Decimal(q_treeitem.text(9)) q_dict['drawunit'] = q_treeitem.text(10) q_dict['loss'] = q_treeitem.text(17) q_dict['precision'] = int(q_treeitem.text(22)) return q_dict @pyqtSlot() def on_pushButton_cancel_clicked(self): self.close()