def quotation_status_delete(sender, **extra): """ 状态跟踪 - 删除状态 1、明细删除状态同步更新 :param sender: :param extra: :return: """ # print(sender, extra) quotation_id = extra.get('quotation_id') status_delete = extra.get('status_delete') current_time = extra.get('current_time') if not quotation_id: return quotation_items = get_quotation_items_rows(quotation_id=quotation_id) result = True for quotation_item in quotation_items: quotation_item_id = quotation_item.id quotation_item_data = { 'status_delete': status_delete, 'delete_time': current_time, 'update_time': current_time, } result = result and edit_quotation_items(quotation_item_id, quotation_item_data) return result
def pdf(quotation_id): """ 文件下载 :param quotation_id: :return: """ quotation_info = get_quotation_row_by_id(quotation_id) # 检查资源是否存在 if not quotation_info: abort(404) # 检查资源是否删除 if quotation_info.status_delete == STATUS_DEL_OK: abort(410) quotation_print_date = time_utc_to_local( quotation_info.update_time).strftime('%Y-%m-%d') quotation_code = '%s%s' % ( g.QUOTATION_PREFIX, time_utc_to_local( quotation_info.create_time).strftime('%y%m%d%H%M%S')) # 获取客户公司信息 customer_info = get_customer_row_by_id(quotation_info.customer_cid) # 获取客户联系方式 customer_contact_info = get_customer_contact_row_by_id( quotation_info.customer_contact_id) # 获取报价人员信息 user_info = get_user_row_by_id(quotation_info.uid) quotation_items = get_quotation_items_rows(quotation_id=quotation_id) # 文档信息 document_info = DOCUMENT_INFO.copy() document_info['TITLE'] = _('quotation download') template_name = 'quotation/pdf.html' html = render_template(template_name, quotation_id=quotation_id, quotation_info=quotation_info, customer_info=customer_info, customer_contact_info=customer_contact_info, user_info=user_info, quotation_items=quotation_items, quotation_print_date=quotation_print_date, quotation_code=quotation_code, **document_info) # return html return render_pdf( html=HTML(string=html), stylesheets=[CSS(string='@page {size:A4; margin:35px;}')], download_filename='报价单.pdf'.encode('utf-8'))
def preview(quotation_id): """ 打印预览 :param quotation_id: :return: """ quotation_info = get_quotation_row_by_id(quotation_id) # 检查资源是否存在 if not quotation_info: abort(404) # 检查资源是否删除 if quotation_info.status_delete == STATUS_DEL_OK: abort(410) quotation_print_date = time_utc_to_local( quotation_info.update_time).strftime('%Y-%m-%d') quotation_code = '%s%s' % ( g.QUOTATION_PREFIX, time_utc_to_local( quotation_info.create_time).strftime('%y%m%d%H%M%S')) # 获取客户公司信息 customer_info = get_customer_row_by_id(quotation_info.customer_cid) # 获取客户联系方式 customer_contact_info = get_customer_contact_row_by_id( quotation_info.customer_contact_id) # 获取报价人员信息 user_info = get_user_row_by_id(quotation_info.uid) quotation_items = get_quotation_items_rows(quotation_id=quotation_id) # 文档信息 document_info = DOCUMENT_INFO.copy() document_info['TITLE'] = _('quotation preview') template_name = 'quotation/preview.html' return render_template(template_name, quotation_id=quotation_id, quotation_info=quotation_info, customer_info=customer_info, customer_contact_info=customer_contact_info, user_info=user_info, quotation_items=quotation_items, quotation_print_date=quotation_print_date, quotation_code=quotation_code, **document_info)
def edit(quotation_id): """ 报价编辑 """ quotation_info = get_quotation_row_by_id(quotation_id) # 检查资源是否存在 if not quotation_info: abort(404) # 检查资源是否删除 if quotation_info.status_delete == STATUS_DEL_OK: abort(410) template_name = 'quotation/edit.html' # 加载编辑表单 form = QuotationEditForm(request.form) form.uid.choices = get_user_choices() form.status_order.choices = STATUS_ORDER_CHOICES # 文档信息 document_info = DOCUMENT_INFO.copy() document_info['TITLE'] = _('quotation edit') # 进入编辑页面 if request.method == 'GET': # 获取明细 quotation_items = get_quotation_items_rows(quotation_id=quotation_id) # 表单赋值 form.uid.data = quotation_info.uid form.customer_cid.data = quotation_info.customer_cid form.customer_contact_id.data = quotation_info.customer_contact_id form.delivery_way.data = quotation_info.delivery_way form.note.data = quotation_info.note form.status_order.data = quotation_info.status_order form.amount_quotation.data = quotation_info.amount_quotation # form.quotation_items = quotation_items while len(form.quotation_items) > 0: form.quotation_items.pop_entry() for quotation_item in quotation_items: quotation_item_form = QuotationItemEditForm() quotation_item_form.id = quotation_item.id quotation_item_form.quotation_id = quotation_item.quotation_id quotation_item_form.uid = quotation_item.uid quotation_item_form.enquiry_production_model = quotation_item.enquiry_production_model quotation_item_form.enquiry_quantity = quotation_item.enquiry_quantity quotation_item_form.production_id = quotation_item.production_id quotation_item_form.production_brand = quotation_item.production_brand quotation_item_form.production_model = quotation_item.production_model quotation_item_form.production_sku = quotation_item.production_sku quotation_item_form.note = quotation_item.note quotation_item_form.quantity = quotation_item.quantity quotation_item_form.unit_price = quotation_item.unit_price quotation_item_form.delivery_time = quotation_item.delivery_time quotation_item_form.status_ordered = quotation_item.status_ordered form.quotation_items.append_entry(quotation_item_form) # 渲染页面 return render_template(template_name, quotation_id=quotation_id, form=form, **document_info) # 处理编辑请求 if request.method == 'POST': # 增删数据行不需要校验表单 # 表单新增空行 if form.data_line_add.data is not None: if form.quotation_items.max_entries and len( form.quotation_items.entries ) >= form.quotation_items.max_entries: flash('最多创建%s条记录' % form.quotation_items.max_entries, 'danger') else: form.quotation_items.append_entry() return render_template(template_name, quotation_id=quotation_id, form=form, **document_info) # 表单删除一行 if form.data_line_del.data is not None: if form.quotation_items.min_entries and len( form.quotation_items.entries ) <= form.quotation_items.min_entries: flash('最少保留%s条记录' % form.quotation_items.min_entries, 'danger') else: data_line_index = form.data_line_del.data form.quotation_items.entries.pop(data_line_index) return render_template(template_name, quotation_id=quotation_id, form=form, **document_info) # 表单校验失败 if not form.validate_on_submit(): flash(_('Edit Failure'), 'danger') # flash(form.errors, 'danger') # flash(form.quotation_items.errors, 'danger') return render_template(template_name, quotation_id=quotation_id, form=form, **document_info) # 表单校验成功 # 获取明细 quotation_items = get_quotation_items_rows(quotation_id=quotation_id) quotation_items_ids = [item.id for item in quotation_items] # 数据新增、数据删除、数据修改 quotation_items_ids_new = [] amount_quotation = 0 for quotation_item in form.quotation_items.entries: # 错误 if quotation_item.form.id.data and quotation_item.form.id.data not in quotation_items_ids: continue quotation_item_data = { 'quotation_id': quotation_id, 'uid': form.uid.data, 'customer_cid': form.customer_cid.data, 'customer_company_name': get_customer_row_by_id(form.customer_cid.data).company_name, 'enquiry_production_model': quotation_item.form.enquiry_production_model.data, 'enquiry_quantity': quotation_item.form.enquiry_quantity.data, 'production_id': quotation_item.form.production_id.data, 'production_brand': quotation_item.form.production_brand.data, 'production_model': quotation_item.form.production_model.data, 'production_sku': quotation_item.form.production_sku.data, 'note': quotation_item.form.note.data, 'delivery_time': quotation_item.form.delivery_time.data, 'quantity': quotation_item.form.quantity.data, 'unit_price': quotation_item.form.unit_price.data, 'status_ordered': quotation_item.form.status_ordered.data, } if not quotation_item.form.id.data: # 新增 add_quotation_items(quotation_item_data) amount_quotation += quotation_item_data[ 'quantity'] * quotation_item_data['unit_price'] else: # 修改 edit_quotation_items(quotation_item.form.id.data, quotation_item_data) amount_quotation += quotation_item_data[ 'quantity'] * quotation_item_data['unit_price'] quotation_items_ids_new.append(quotation_item.form.id.data) # 删除 quotation_items_ids_del = list( set(quotation_items_ids) - set(quotation_items_ids_new)) for quotation_items_id in quotation_items_ids_del: delete_quotation_items(quotation_items_id) # 更新报价 current_time = datetime.utcnow() quotation_data = { 'customer_cid': form.customer_cid.data, 'uid': form.uid.data, 'customer_contact_id': form.customer_contact_id.data, 'delivery_way': form.delivery_way.data, 'note': form.note.data, 'status_order': form.status_order.data, 'amount_production': amount_quotation, 'amount_quotation': amount_quotation, 'update_time': current_time, } result = edit_quotation(quotation_id, quotation_data) # 编辑操作成功 if result: flash(_('Edit Success'), 'success') return redirect( request.args.get('next') or url_for('quotation.lists')) # 编辑操作失败 else: flash(_('Edit Failure'), 'danger') return render_template(template_name, quotation_id=quotation_id, form=form, **document_info)
def add(): """ 创建报价 :return: """ template_name = 'quotation/add.html' # 文档信息 document_info = DOCUMENT_INFO.copy() document_info['TITLE'] = _('quotation add') # 加载创建表单 form = QuotationAddForm(request.form) form.uid.choices = get_user_choices() form.uid.data = current_user.id form.status_order.choices = STATUS_ORDER_CHOICES # 进入创建页面 if request.method == 'GET': # 克隆单据 from_type = request.args.get('from_type') from_id = request.args.get('from_id', type=int) # 克隆单据 - 报价单 if from_type == 'quotation' and from_id: quotation_id = from_id quotation_info = get_quotation_row_by_id(quotation_id) # 检查资源是否存在 if not quotation_info: abort(404) # 检查资源是否删除 if quotation_info.status_delete == STATUS_DEL_OK: abort(410) # 获取明细 quotation_items = get_quotation_items_rows( quotation_id=quotation_id) # 表单赋值 form.uid.data = quotation_info.uid form.customer_cid.data = quotation_info.customer_cid form.customer_contact_id.data = quotation_info.customer_contact_id form.delivery_way.data = quotation_info.delivery_way form.note.data = quotation_info.note form.status_order.data = quotation_info.status_order form.amount_quotation.data = quotation_info.amount_quotation # form.quotation_items = quotation_items while len(form.quotation_items) > 0: form.quotation_items.pop_entry() for quotation_item in quotation_items: quotation_item_form = QuotationItemEditForm() quotation_item_form.id = quotation_item.id quotation_item_form.quotation_id = quotation_item.quotation_id quotation_item_form.uid = quotation_item.uid quotation_item_form.enquiry_production_model = quotation_item.enquiry_production_model quotation_item_form.enquiry_quantity = quotation_item.enquiry_quantity quotation_item_form.production_id = quotation_item.production_id quotation_item_form.production_brand = quotation_item.production_brand quotation_item_form.production_model = quotation_item.production_model quotation_item_form.production_sku = quotation_item.production_sku quotation_item_form.note = quotation_item.note quotation_item_form.quantity = quotation_item.quantity quotation_item_form.unit_price = quotation_item.unit_price quotation_item_form.delivery_time = quotation_item.delivery_time quotation_item_form.status_ordered = quotation_item.status_ordered form.quotation_items.append_entry(quotation_item_form) # 渲染页面 return render_template(template_name, form=form, **document_info) # 处理创建请求 if request.method == 'POST': # 表单新增空行 if form.data_line_add.data is not None: if form.quotation_items.max_entries and len( form.quotation_items.entries ) >= form.quotation_items.max_entries: flash('最多创建%s条记录' % form.quotation_items.max_entries, 'danger') else: form.quotation_items.append_entry() return render_template(template_name, form=form, **document_info) # 表单删除一行 if form.data_line_del.data is not None: if form.quotation_items.min_entries and len( form.quotation_items.entries ) <= form.quotation_items.min_entries: flash('最少保留%s条记录' % form.quotation_items.min_entries, 'danger') else: data_line_index = form.data_line_del.data form.quotation_items.entries.pop(data_line_index) return render_template(template_name, form=form, **document_info) # 表单校验失败 if not form.validate_on_submit(): flash(_('Add Failure'), 'danger') # flash(form.errors, 'danger') return render_template(template_name, form=form, **document_info) # 表单校验成功 # 创建报价 current_time = datetime.utcnow() quotation_data = { 'uid': form.uid.data, 'customer_cid': form.customer_cid.data, 'customer_contact_id': form.customer_contact_id.data, 'delivery_way': form.delivery_way.data, 'note': form.note.data, 'status_order': form.status_order.data, 'expiry_date': (datetime.utcnow() + timedelta(days=7)).strftime('%Y-%m-%d'), 'create_time': current_time, 'update_time': current_time, } quotation_id = add_quotation(quotation_data) amount_quotation = 0 for quotation_item in form.quotation_items.entries: current_time = datetime.utcnow() quotation_item_data = { 'quotation_id': quotation_id, 'uid': form.uid.data, 'customer_cid': form.customer_cid.data, 'customer_company_name': get_customer_row_by_id(form.customer_cid.data).company_name, 'enquiry_production_model': quotation_item.form.enquiry_production_model.data, 'enquiry_quantity': quotation_item.form.enquiry_quantity.data, 'production_id': quotation_item.form.production_id.data, 'production_brand': quotation_item.form.production_brand.data, 'production_model': quotation_item.form.production_model.data, 'production_sku': quotation_item.form.production_sku.data, 'note': quotation_item.form.note.data, 'delivery_time': quotation_item.form.delivery_time.data, 'quantity': quotation_item.form.quantity.data, 'unit_price': quotation_item.form.unit_price.data, 'status_ordered': quotation_item.form.status_ordered.data, 'create_time': current_time, 'update_time': current_time, } # 新增 add_quotation_items(quotation_item_data) amount_quotation += (quotation_item_data['quantity'] or 0) * (quotation_item_data['unit_price'] or 0) # 更新报价 quotation_data = { 'amount_production': amount_quotation, 'amount_quotation': amount_quotation, 'update_time': current_time, } result = edit_quotation(quotation_id, quotation_data) # todo 事务 # 明细保存 # 总表保存 # 创建操作成功 if result: flash(_('Add Success'), 'success') return redirect( request.args.get('next') or url_for('quotation.lists')) # 创建操作失败 else: flash(_('Add Failure'), 'danger') return render_template(template_name, form=form, **document_info)
def lists(): """ 报价列表 :return: """ template_name = 'quotation/items/lists.html' # 文档信息 document_info = DOCUMENT_INFO.copy() document_info['TITLE'] = _('quotation item lists') # 搜索条件 form = QuotationItemsSearchForm(request.form) # form.uid.choices = get_quotation_user_list_choices() # app.logger.info('') search_condition = [ QuotationItems.status_delete == STATUS_DEL_NO, ] if request.method == 'POST': # 表单校验失败 if not form.validate_on_submit(): flash(_('Search Failure'), 'danger') # 单独处理csrf_token if hasattr(form, 'csrf_token') and getattr(form, 'csrf_token').errors: map(lambda x: flash(x, 'danger'), form.csrf_token.errors) else: if form.customer_cid.data and form.customer_company_name.data: search_condition.append(QuotationItems.customer_cid == form.customer_cid.data) if form.production_model.data: # 注意查询效率 search_condition.append( or_( QuotationItems.production_model.like('%%%s%%' % form.production_model.data), QuotationItems.enquiry_production_model.like('%%%s%%' % form.production_model.data) ) ) if form.start_create_time.data: search_condition.append(QuotationItems.create_time >= form.start_create_time.data) if form.end_create_time.data: search_condition.append(QuotationItems.create_time <= form.end_create_time.data) # 处理导出 if form.op.data == OPERATION_EXPORT: # 检查导出权限 if not permission_quotation_section_export.can(): abort(403) column_names = QuotationItems.__table__.columns.keys() query_sets = get_quotation_items_rows(*search_condition) return excel.make_response_from_query_sets( query_sets=query_sets, column_names=column_names, file_type='csv', file_name='%s.csv' % _('quotation item lists') ) # 翻页数据 pagination = get_quotation_items_pagination(form.page.data, PER_PAGE_BACKEND, *search_condition) # 渲染模板 return render_template( template_name, form=form, pagination=pagination, **document_info )