You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
151 lines
7.2 KiB
151 lines
7.2 KiB
# -*- coding: utf-8 -*-
|
|
from decimal import Decimal
|
|
|
|
from django.utils.text import wrap
|
|
|
|
from ..models import Faktura, FakturaItem
|
|
from ..forms import FakturaForm, FakturaItemForm
|
|
from .. import utils
|
|
|
|
from .base_views import BaseItemsViews
|
|
from .mixins import AddByInvoiceMethodMixin
|
|
|
|
|
|
class FakturaViews(BaseItemsViews, AddByInvoiceMethodMixin):
|
|
"""Views для накладных торг12."""
|
|
|
|
MODEL = Faktura # модель документа
|
|
FORM_CLASS = FakturaForm # форма документа
|
|
|
|
ITEM_MODEL = FakturaItem # модель табличной части документа
|
|
ITEM_FORM_CLASS = FakturaItemForm # форма табличной части документа
|
|
ITEM_FORM_PREFIX = 'faktura_items' # префикс формы табличной части
|
|
|
|
# поля, по которым можно фильтровать список документов
|
|
# должны поддерживаться в docs.filters.build_filterset_class !
|
|
FILTER_FIELDS = ('signed_status', 'client', 'invoice', 'doc_date',)
|
|
|
|
# по какому полю суммировать табличную часть документа при показе списком
|
|
LIST_SUM_FIELD = 'faktura_items__total_price'
|
|
|
|
# префикс именованных урлов этого типа документов, для передачи в шаблон
|
|
URL_PREFIX = 'docs_faktura_'
|
|
|
|
# именованные урлы операций
|
|
URL_LIST = 'docs_faktura_list'
|
|
URL_EDIT = 'docs_faktura_edit'
|
|
|
|
# пути к шаблонам
|
|
TEMPLATE_LIST = 'docs/faktura/list.html'
|
|
TEMPLATE_FORM = 'docs/faktura/form.html'
|
|
|
|
# для генерации pdf/xls
|
|
PDF_TEMPLATE = 'docs/faktura/as_pdf.html'
|
|
XLS_TEMPLATE = 'faktura.xls'
|
|
FILENAME = u'Накладная № %s, %s' # без расширения
|
|
|
|
# --- грамматика для вывода наименований в шаблонах
|
|
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
|
|
|