# -*- coding: utf-8 -*- from decimal import Decimal from django.utils.text import wrap from ..models import Nakladn, NakladnItem from ..forms import NakladnForm, NakladnItemForm from ..filters import NakladnFilterSet from .. import utils from .base_views import BaseItemsViews from .mixins import AddByInvoiceMethodMixin class NakladnViews(BaseItemsViews, AddByInvoiceMethodMixin): """Views для накладных торг12.""" MODEL = Nakladn # модель документа FORM_CLASS = NakladnForm # форма документа ITEM_MODEL = NakladnItem # модель табличной части документа ITEM_FORM_CLASS = NakladnItemForm # форма табличной части документа ITEM_FORM_PREFIX = 'nakladn_items' # префикс формы табличной части FILTERSET_CLASS = NakladnFilterSet # фильтры # по какому полю суммировать табличную часть документа при показе списком LIST_SUM_FIELD = 'nakladn_items__total_price' # префикс именованных урлов этого типа документов, для передачи в шаблон URL_PREFIX = 'docs_nakladn_' # именованные урлы операций URL_LIST = 'docs_nakladn_list' URL_EDIT = 'docs_nakladn_edit' # пути к шаблонам TEMPLATE_LIST = 'docs/nakladn/list.html' TEMPLATE_FORM = 'docs/nakladn/form.html' TEMPLATE_LINKED_DOCS_LIST = 'docs/parts/linked_docs_list.html' # для генерации pdf/xls PDF_TEMPLATE = 'docs/nakladn/as_pdf.html' XLS_TEMPLATE = 'nakladn.xls' FILENAME = u'Накладная № %s, %s' # без расширения MAYBE_SIGNED = True # --- грамматика для вывода наименований в шаблонах PADEJI = { 'imenit': u'накладная', # кто? что? 'rodit': u'накладной', # кого? чего? 'dateln': u'накладной', # кому? чему? 'vinit': u'накладную', # кого? что? 'tvorit': u'накладной', # кем? чем? 'predlojn': u'накладной', # о ком? о чём? } PADEJI_MNOJ = { 'imenit': u'накладные', # кто? что? 'rodit': u'накладных', # кого? чего? 'dateln': u'накладным', # кому? чему? 'vinit': u'накладные', # кого? что? 'tvorit': u'накладными', # кем? чем? 'predlojn': u'накладных', # о ком? о чём? } def prepare(self, obj, obj_items, export_to=None): """Изменить/подмешать дополнительные поля к документу.""" obj.sum_total_nds = Decimal('0.00') obj.sum_full_total_price = Decimal('0.00') obj.sum_qty = Decimal('0.00') obj.sum_clean_total_price = Decimal('0.00') # строки табличной части for item in obj_items: item.clean_price = utils.calc_clean_price(item) item.clean_total_price = utils.calc_clean_total_price(item) item.total_nds = utils.calc_total_nds(item) item.full_total_price = utils.calc_full_total_price(item) # итого табличной части obj.sum_total_nds += item.total_nds obj.sum_full_total_price += item.full_total_price obj.sum_qty += item.qty obj.sum_clean_total_price += item.clean_total_price # разбивка на страницы и итого по странице # величины и размеры - приблизительные и подобраны опытным путем! if export_to == 'pdf': page_rows = 42 # высота в строках + рамки и вертикальные отступы doc_header_rows = 20 # TODO: рассчитывать! doc_footer_rows = 26 tbl_header_rows = 6 + 1 # шапка таблицы tbl_page_footer_rows = 1 + 1 # подитог (итого по странице) таблицы tbl_footer_rows = 1 + 1 # подвал таблицы curr_rows = doc_header_rows + tbl_header_rows # print '(start) curr_rows =', curr_rows # если шрифт не моноширный, то в строчках умещается разное количество символов! chars_per_line = 38 # для наименования last_page_item_idx = 0 def calc_itogo(item, start, stop): # подитоги по странице item.sum_qty = 0 item.sum_clean_total_price = 0 item.sum_total_nds = 0 item.sum_full_total_price = 0 for x in obj_items[start:stop]: item.sum_qty += x.qty item.sum_clean_total_price += x.clean_total_price item.sum_total_nds += x.total_nds item.sum_full_total_price += x.full_total_price for idx, item in enumerate(obj_items): just_calc_itogo = False # сколько строк займет строка name = wrap(item.name, chars_per_line) name_rows = max(1, len(name.split('\n'))) + 1 # + отступ/рамка # print 'name_rows =', name_rows, # print '(+%s)' % (tbl_page_footer_rows + tbl_footer_rows) # строка, подитог и итог не помещаются на странице if (curr_rows + name_rows + tbl_page_footer_rows + tbl_footer_rows > page_rows): if idx == 0: item.pdf_pagebreak_before = True prev_item = item else: prev_item = obj_items[idx-1] # print '--- new page', \ # curr_rows + name_rows + tbl_page_footer_rows + tbl_footer_rows, \ # '>', page_rows prev_item.pdf_pagebreak_after = True prev_item.pdf_page_footer = True calc_itogo(prev_item, last_page_item_idx, idx) just_calc_itogo = True last_page_item_idx = idx curr_rows = tbl_header_rows + name_rows else: curr_rows += name_rows else: if len(obj_items): # только если были записи в табличной части if not just_calc_itogo: item.pdf_page_footer = True calc_itogo(item, last_page_item_idx, idx) curr_rows += tbl_page_footer_rows curr_rows += tbl_footer_rows if curr_rows + doc_footer_rows > page_rows: item.pdf_pagebreak_after = True # print 'curr_rows =', curr_rows