From 75c72ce8a56adf55e788ec1c2382d02daba282ca Mon Sep 17 00:00:00 2001
From: Marc Aymerich
Please select a " "payment source for the selected bills" @@ -56,138 +56,183 @@ msgstr "" "Una vegada la factura estigui tancada no podrà ser modificada.
Si us "
"plau selecciona un mètode de pagament per les factures seleccionades"
-#: actions.py:107
+#: actions.py:110
msgid "Close"
msgstr "Tanca"
-#: actions.py:125
+#: actions.py:124
msgid "One bill has been sent."
msgstr "S'ha creat una factura"
-#: actions.py:126
+#: actions.py:125
#, python-format
msgid "%i bills have been sent."
msgstr "S'han enviat %i factures."
-#: actions.py:128
+#: actions.py:127
msgid "Resend"
msgstr "Reenviat"
-#: actions.py:189
+#: actions.py:188
#, python-format
msgid "%(norders)s orders and %(nlines)s lines undoed."
msgstr "%(norders)s ordres i %(nlines)s línies desfetes."
-#: actions.py:208
+#: actions.py:207
msgid "Lines moved"
msgstr "Línies mogudes"
-#: admin.py:49 admin.py:93 admin.py:128 forms.py:11
+#: actions.py:219
+msgid "Selected bills should be in closed state"
+msgstr "Les factures seleccionades han d'estar en estat obert"
+
+#: actions.py:236
+#, python-format
+msgid "%(type)s of %(related_type)s %(number)s and creation date %(date)s"
+msgstr "%(type)s de %(related_type)s %(number)s amb data de creació %(date)s"
+
+#: actions.py:243
+#, python-format
+msgid "%(related_type)s %(number)s subtotal for tax %(tax)s%%"
+msgstr "%(related_type)s %(number)s subtotal %(tax)s%%"
+
+#: actions.py:259
+#, python-format
+msgid "One amendment bill have been generated."
+msgstr "S'ha creat una transacció"
+
+#: actions.py:260
+#, python-format
+msgid "%(num)i amendment bills have been generated."
+msgstr "S'han creat les %(num)i següents transaccions"
+
+#: actions.py:263
+msgid "Amend"
+msgstr ""
+
+#: admin.py:54 admin.py:98 admin.py:133 forms.py:11
+#: templates/admin/bills/report.html:43
msgid "Total"
msgstr "Total"
-#: admin.py:80
+#: admin.py:85
msgid "Description"
msgstr "Descripció"
-#: admin.py:88
+#: admin.py:93
msgid "Subtotal"
msgstr "Subtotal"
-#: admin.py:118
+#: admin.py:123
msgid "Is open"
msgstr "És oberta"
-#: admin.py:123
+#: admin.py:128
msgid "Subline"
msgstr "Sublínia"
-#: admin.py:157
+#: admin.py:162
msgid "No bills selected."
msgstr "No hi ha factures seleccionades"
-#: admin.py:164
+#: admin.py:169
#, python-format
msgid "Manage %s bill lines."
msgstr "Gestiona %s línies de factura."
-#: admin.py:166
+#: admin.py:171
msgid "Bill not in open state."
msgstr "La factura no està en estat obert"
-#: admin.py:169
+#: admin.py:174
msgid "Not all bills are in open state."
msgstr "No totes les factures estan en estat obert"
-#: admin.py:170
+#: admin.py:175
msgid "Manage bill lines of multiple bills."
msgstr "Gestiona línies de factura de multiples factures."
-#: admin.py:190
+#: admin.py:195
msgid "Raw"
msgstr "Raw"
-#: admin.py:208
+#: admin.py:214 models.py:72
msgid "Created"
msgstr "Creada"
-#: admin.py:213
+#: admin.py:220
msgid "lines"
msgstr "línies"
-#: admin.py:218 templates/bills/microspective.html:118
+#: admin.py:225 filters.py:44 templates/bills/microspective.html:118
msgid "total"
msgstr "total"
-#: admin.py:226 models.py:88 models.py:352
+#: admin.py:233 models.py:103 models.py:446
msgid "type"
msgstr "tipus"
-#: admin.py:243
+#: admin.py:250
msgid "Payment"
msgstr "Pagament"
-#: filters.py:17
+#: filters.py:19
msgid "All"
msgstr "Tot"
-#: filters.py:18 models.py:78
+#: filters.py:20 models.py:87
msgid "Invoice"
msgstr "Factura"
-#: filters.py:19 models.py:79
+#: filters.py:21 models.py:88
msgid "Amendment invoice"
msgstr "Factura rectificativa"
-#: filters.py:20 models.py:80
+#: filters.py:22 models.py:89
msgid "Fee"
msgstr "Quota de soci"
-#: filters.py:21
+#: filters.py:23
msgid "Amendment fee"
msgstr "Rectificació de quota de soci"
-#: filters.py:22
+#: filters.py:24
msgid "Pro-forma"
msgstr "Pro-forma"
-#: filters.py:41
-msgid "positive price"
-msgstr "preu positiu"
-
-#: filters.py:46 filters.py:64
-msgid "Yes"
-msgstr "Si"
-
-#: filters.py:47 filters.py:65
-msgid "No"
-msgstr "No"
-
-#: filters.py:59
+#: filters.py:66
msgid "has bill contact"
msgstr "té contacte de facturació"
-#: forms.py:9
+#: filters.py:71
+msgid "Yes"
+msgstr "Si"
+
+#: filters.py:72
+msgid "No"
+msgstr "No"
+
+#: filters.py:83
+msgid "payment state"
+msgstr "Pagament"
+
+#: filters.py:88 models.py:71
+msgid "Open"
+msgstr ""
+
+#: filters.py:89 models.py:75
+msgid "Paid"
+msgstr "Pagat"
+
+#: filters.py:90
+msgid "Pending"
+msgstr "Pendent"
+
+#: filters.py:91 models.py:78
+msgid "Bad debt"
+msgstr "Incobrable"
+
+#: forms.py:9 templates/admin/bills/report.html:37
msgid "Number"
msgstr "Número"
@@ -219,7 +264,7 @@ msgstr "Relacionat"
msgid "Main"
msgstr "Principal"
-#: models.py:23 models.py:86
+#: models.py:23 models.py:99
msgid "account"
msgstr "compte"
@@ -251,141 +296,186 @@ msgstr "Introdueix un codi postal vàlid."
msgid "country"
msgstr "país"
-#: models.py:35
+#: models.py:35 templates/admin/bills/report.html:38
msgid "VAT number"
msgstr "NIF"
-#: models.py:67
-msgid "Paid"
-msgstr "Pagat"
+#: models.py:73
+msgid "Processed"
+msgstr ""
-#: models.py:68
-msgid "Pending"
-msgstr "Pendent"
+#: models.py:74
+#, fuzzy
+#| msgid "amended line"
+msgid "Amended"
+msgstr "línia rectificada"
-#: models.py:69
-msgid "Bad debt"
-msgstr "Incobrable"
+#: models.py:76
+msgid "Incomplete"
+msgstr ""
-#: models.py:81
+#: models.py:77
+msgid "Executed"
+msgstr ""
+
+#: models.py:90
msgid "Amendment Fee"
msgstr "Rectificació de quota de soci"
-#: models.py:82
+#: models.py:91
msgid "Pro forma"
msgstr "Pro forma"
-#: models.py:85
+#: models.py:98
msgid "number"
msgstr "número"
-#: models.py:89
+#: models.py:101
+#, fuzzy
+#| msgid "amended line"
+msgid "amend of"
+msgstr "línia rectificada"
+
+#: models.py:104
msgid "created on"
msgstr "creat el"
-#: models.py:90
+#: models.py:105
msgid "closed on"
msgstr "tancat el"
-#: models.py:91
+#: models.py:106
msgid "open"
msgstr "obert"
-#: models.py:92
+#: models.py:107
msgid "sent"
msgstr "enviat"
-#: models.py:93
+#: models.py:108
msgid "due on"
msgstr "es deu"
-#: models.py:94
+#: models.py:109
msgid "updated on"
msgstr "actualitzada el"
-#: models.py:97
+#: models.py:112
msgid "comments"
msgstr "comentaris"
-#: models.py:98
+#: models.py:113
msgid "HTML"
msgstr "HTML"
-#: models.py:285
+#: models.py:192
+#, python-format
+msgid "Type %s is not an amendment."
+msgstr ""
+
+#: models.py:194
+msgid "Amend of related account doesn't match bill account."
+msgstr ""
+
+#: models.py:199
+#, python-format
+msgid "Type %s requires an amend of link."
+msgstr ""
+
+#: models.py:378
msgid "bill"
msgstr "factura"
-#: models.py:286 models.py:350 templates/bills/microspective.html:73
+#: models.py:379 models.py:444 templates/bills/microspective.html:73
msgid "description"
msgstr "descripció"
-#: models.py:287
+#: models.py:380
msgid "rate"
msgstr "tarifa"
-#: models.py:288
+#: models.py:381
msgid "quantity"
msgstr "quantitat"
-#: models.py:289
+#: models.py:383
#, fuzzy
#| msgid "quantity"
msgid "Verbose quantity"
msgstr "quantitat"
-#: models.py:290 templates/bills/microspective.html:77
+#: models.py:384 templates/bills/microspective.html:77
#: templates/bills/microspective.html:111
msgid "subtotal"
msgstr "subtotal"
-#: models.py:291
+#: models.py:385
msgid "tax"
msgstr "impostos"
-#: models.py:292
+#: models.py:386
msgid "start"
msgstr "iniciar"
-#: models.py:293
+#: models.py:387
msgid "end"
msgstr "finalitzar"
-#: models.py:295
+#: models.py:389
msgid "Informative link back to the order"
msgstr "Enllaç informatiu de l'ordre"
-#: models.py:296
+#: models.py:390
msgid "order billed"
msgstr "ordre facturada"
-#: models.py:297
+#: models.py:391
msgid "order billed until"
msgstr "ordre facturada fins a"
-#: models.py:298
+#: models.py:392
msgid "created"
msgstr "creada"
-#: models.py:300
+#: models.py:394
msgid "amended line"
msgstr "línia rectificada"
-#: models.py:343
+#: models.py:437
msgid "Volume"
msgstr "Volum"
-#: models.py:344
+#: models.py:438
msgid "Compensation"
msgstr "Compensació"
-#: models.py:345
+#: models.py:439
msgid "Other"
msgstr "Altre"
-#: models.py:349
+#: models.py:443
msgid "bill line"
msgstr "línia de factura"
+#: templates/admin/bills/report.html:39
+msgid "Contact"
+msgstr ""
+
+#: templates/admin/bills/report.html:40
+#, fuzzy
+#| msgid "Due date"
+msgid "Close date"
+msgstr "Data de pagament"
+
+#: templates/admin/bills/report.html:41
+msgid "Base"
+msgstr ""
+
+#: templates/admin/bills/report.html:42 templates/bills/microspective.html:111
+#: templates/bills/microspective.html:114
+msgid "VAT"
+msgstr "IVA"
+
#: templates/bills/microspective-fee.html:107
msgid "Due date"
msgstr "Data de pagament"
@@ -433,11 +523,6 @@ msgstr "hrs/qnt"
msgid "rate/price"
msgstr "tarifa/preu"
-#: templates/bills/microspective.html:111
-#: templates/bills/microspective.html:114
-msgid "VAT"
-msgstr "IVA"
-
#: templates/bills/microspective.html:114
msgid "taxes"
msgstr "impostos"
@@ -451,6 +536,7 @@ msgid "PAYMENT"
msgstr "PAGAMENT"
#: templates/bills/microspective.html:140
+#, python-format
msgid ""
"\n"
" You can pay our %(type)s by bank transfer.
\n"
@@ -483,3 +569,6 @@ msgstr ""
" contacta amb nosaltres a %(email)s. Et respondrem el més "
"ràpidament possible.\n"
" "
+
+#~ msgid "positive price"
+#~ msgstr "preu positiu"
diff --git a/orchestra/contrib/bills/locale/es/LC_MESSAGES/django.mo b/orchestra/contrib/bills/locale/es/LC_MESSAGES/django.mo
index 258c2c4c2ca0b50aee0744613f6d614dba7082f8..a9cc33e6e0c7562990a2cf30181a618a681059d6 100644
GIT binary patch
delta 2107
zcmZ{kU5Hd=7{?!NcXiit(=5$QM{RYt(p|IE6qI(iEO1*hlOm+fob!%*Xy%;RGiP=)
zf*}aPZX~9lFsZBR#tOs>Met%1ybuYmq@WLwq9h11=;Nl}f9Bo2>t&wvdq1A@KF{-i
z4)fuPpVv0NTiWrSF?M0Au$%MD#^L2#crX@rn%#ii@B;i3E`?{h%!c75I0_dnFxw6H
z!`t9-xCEYrgYXO30l$X};dRJW4f~DBt!(@O`L#~vu#kti#B(K7PV3=vxDo2YJy7qB
z!aLwTI0;{d^1BKNWWPfB{qFe}Ttj?HGur?PP>y?{0*%4j;WJQyijZRM2;^N$pc0?<
z=WjxOcFeO0<#!S)@F%bbehwGGv#?9?FEUZU%TSJA>i}MZEy?`)I@E
Please select a " "payment source for the selected bills" @@ -56,138 +56,180 @@ msgstr "" "Una vez cerrada la factura ya no se podrá modificar.
Por favor " "seleciona un metodo de pago para las facturas seleccionadas" -#: actions.py:107 +#: actions.py:110 msgid "Close" msgstr "Cerrar" -#: actions.py:125 +#: actions.py:124 msgid "One bill has been sent." msgstr "Se ha enviado una factura" -#: actions.py:126 +#: actions.py:125 #, python-format msgid "%i bills have been sent." msgstr "" -#: actions.py:128 +#: actions.py:127 msgid "Resend" msgstr "" -#: actions.py:189 +#: actions.py:188 #, python-format msgid "%(norders)s orders and %(nlines)s lines undoed." msgstr "" -#: actions.py:208 +#: actions.py:207 msgid "Lines moved" msgstr "" -#: admin.py:49 admin.py:93 admin.py:128 forms.py:11 +#: actions.py:219 +msgid "Selected bills should be in closed state" +msgstr "Las facturas seleccionadas están en estado abierto" + +#: actions.py:236 +#, python-format +msgid "%(type)s of %(related_type)s %(number)s and creation date %(date)s" +msgstr "%(type)s de %(related_type)s %(number)s con fecha de creación %(date)s" + +#: actions.py:243 +msgid "%(related_type)s %(number)s subtotal for tax %(tax)s%%" +msgstr "%(related_type)s %(number)s subtotal %(tax)s%%" + +#: actions.py:255 +msgid "One amendment bill have been generated." +msgstr "Se ha creado una transacción" + +#: actions.py:256 +msgid "%(num)i amendment bills have been generated." +msgstr "Se han creado %(num)i transacciones" + +#: actions.py:259 +msgid "Amend" +msgstr "" + +#: admin.py:54 admin.py:98 admin.py:133 forms.py:11 +#: templates/admin/bills/report.html:43 msgid "Total" msgstr "" -#: admin.py:80 +#: admin.py:85 msgid "Description" msgstr "" -#: admin.py:88 +#: admin.py:93 msgid "Subtotal" msgstr "" -#: admin.py:118 +#: admin.py:123 msgid "Is open" msgstr "" -#: admin.py:123 +#: admin.py:128 msgid "Subline" msgstr "" -#: admin.py:157 +#: admin.py:162 msgid "No bills selected." msgstr "" -#: admin.py:164 +#: admin.py:169 #, python-format msgid "Manage %s bill lines." msgstr "" -#: admin.py:166 +#: admin.py:171 msgid "Bill not in open state." msgstr "" -#: admin.py:169 +#: admin.py:174 msgid "Not all bills are in open state." msgstr "" -#: admin.py:170 +#: admin.py:175 msgid "Manage bill lines of multiple bills." msgstr "" -#: admin.py:190 +#: admin.py:195 msgid "Raw" msgstr "" -#: admin.py:208 +#: admin.py:214 models.py:72 msgid "Created" msgstr "" -#: admin.py:213 +#: admin.py:220 msgid "lines" msgstr "" -#: admin.py:218 templates/bills/microspective.html:118 +#: admin.py:225 filters.py:44 templates/bills/microspective.html:118 msgid "total" msgstr "" -#: admin.py:226 models.py:88 models.py:352 +#: admin.py:233 models.py:103 models.py:446 msgid "type" msgstr "" -#: admin.py:243 +#: admin.py:250 msgid "Payment" msgstr "Pago" -#: filters.py:17 +#: filters.py:19 msgid "All" msgstr "" -#: filters.py:18 models.py:78 +#: filters.py:20 models.py:87 msgid "Invoice" msgstr "Factura" -#: filters.py:19 models.py:79 +#: filters.py:21 models.py:88 msgid "Amendment invoice" msgstr "Factura rectificative" -#: filters.py:20 models.py:80 +#: filters.py:22 models.py:89 msgid "Fee" msgstr "Quota de socio" -#: filters.py:21 +#: filters.py:23 msgid "Amendment fee" msgstr "Quota rectificativa" -#: filters.py:22 +#: filters.py:24 msgid "Pro-forma" msgstr "" -#: filters.py:41 -msgid "positive price" -msgstr "" - -#: filters.py:46 filters.py:64 -msgid "Yes" -msgstr "" - -#: filters.py:47 filters.py:65 -msgid "No" -msgstr "" - -#: filters.py:59 +#: filters.py:66 msgid "has bill contact" msgstr "" -#: forms.py:9 +#: filters.py:71 +msgid "Yes" +msgstr "" + +#: filters.py:72 +msgid "No" +msgstr "" + +#: filters.py:83 +msgid "payment state" +msgstr "Pago" + +#: filters.py:88 models.py:71 +msgid "Open" +msgstr "" + +#: filters.py:89 models.py:75 +msgid "Paid" +msgstr "" + +#: filters.py:90 +msgid "Pending" +msgstr "" + +#: filters.py:91 models.py:78 +msgid "Bad debt" +msgstr "" + +#: forms.py:9 templates/admin/bills/report.html:37 msgid "Number" msgstr "" @@ -217,7 +259,7 @@ msgstr "" msgid "Main" msgstr "" -#: models.py:23 models.py:86 +#: models.py:23 models.py:99 msgid "account" msgstr "" @@ -249,138 +291,179 @@ msgstr "" msgid "country" msgstr "" -#: models.py:35 +#: models.py:35 templates/admin/bills/report.html:38 msgid "VAT number" msgstr "" -#: models.py:67 -msgid "Paid" +#: models.py:73 +msgid "Processed" msgstr "" -#: models.py:68 -msgid "Pending" +#: models.py:74 +msgid "Amended" +msgstr "Quota rectificativa" + +#: models.py:76 +msgid "Incomplete" msgstr "" -#: models.py:69 -msgid "Bad debt" -msgstr "" - -#: models.py:81 -msgid "Amendment Fee" -msgstr "" - -#: models.py:82 -msgid "Pro forma" -msgstr "" - -#: models.py:85 -msgid "number" -msgstr "" - -#: models.py:89 -msgid "created on" +#: models.py:77 +msgid "Executed" msgstr "" #: models.py:90 -msgid "closed on" +msgid "Amendment Fee" msgstr "" #: models.py:91 -msgid "open" -msgstr "" - -#: models.py:92 -msgid "sent" -msgstr "" - -#: models.py:93 -msgid "due on" -msgstr "" - -#: models.py:94 -msgid "updated on" -msgstr "" - -#: models.py:97 -msgid "comments" +msgid "Pro forma" msgstr "" #: models.py:98 +msgid "number" +msgstr "número" + +#: models.py:101 +msgid "amend of" +msgstr "rectificación de" + +#: models.py:104 +msgid "created on" +msgstr "creado en" + +#: models.py:105 +msgid "closed on" +msgstr "cerrada en" + +#: models.py:106 +msgid "open" +msgstr "abierta" + +#: models.py:107 +msgid "sent" +msgstr "enviada" + +#: models.py:108 +msgid "due on" +msgstr "vencimiento" + +#: models.py:109 +msgid "updated on" +msgstr "actualizada en" + +#: models.py:112 +msgid "comments" +msgstr "comentarios" + +#: models.py:113 msgid "HTML" +msgstr "HTML" + +#: models.py:192 +#, python-format +msgid "Type %s is not an amendment." msgstr "" -#: models.py:285 +#: models.py:194 +msgid "Amend of related account doesn't match bill account." +msgstr "" + +#: models.py:199 +#, python-format +msgid "Type %s requires an amend of link." +msgstr "" + +#: models.py:378 msgid "bill" -msgstr "" +msgstr "factura" -#: models.py:286 models.py:350 templates/bills/microspective.html:73 +#: models.py:379 models.py:444 templates/bills/microspective.html:73 msgid "description" -msgstr "" +msgstr "descripción" -#: models.py:287 +#: models.py:380 msgid "rate" -msgstr "" +msgstr "tarifa" -#: models.py:288 +#: models.py:381 msgid "quantity" -msgstr "" +msgstr "cantidad" -#: models.py:289 +#: models.py:383 msgid "Verbose quantity" -msgstr "" +msgstr "Cantidad" -#: models.py:290 templates/bills/microspective.html:77 +#: models.py:384 templates/bills/microspective.html:77 #: templates/bills/microspective.html:111 msgid "subtotal" -msgstr "" +msgstr "subtotal" -#: models.py:291 +#: models.py:385 msgid "tax" -msgstr "" +msgstr "impuesto" -#: models.py:292 +#: models.py:386 msgid "start" -msgstr "" +msgstr "inicio" -#: models.py:293 +#: models.py:387 msgid "end" -msgstr "" +msgstr "fín" -#: models.py:295 +#: models.py:389 msgid "Informative link back to the order" msgstr "" -#: models.py:296 +#: models.py:390 msgid "order billed" msgstr "" -#: models.py:297 +#: models.py:391 msgid "order billed until" msgstr "" -#: models.py:298 +#: models.py:392 msgid "created" -msgstr "" +msgstr "creado" -#: models.py:300 +#: models.py:394 msgid "amended line" -msgstr "" +msgstr "linea rectificativa" -#: models.py:343 +#: models.py:437 msgid "Volume" -msgstr "" +msgstr "Volumen" -#: models.py:344 +#: models.py:438 msgid "Compensation" -msgstr "" +msgstr "Compensación" -#: models.py:345 +#: models.py:439 msgid "Other" -msgstr "" +msgstr "Otro" -#: models.py:349 +#: models.py:443 msgid "bill line" -msgstr "" +msgstr "linea de factura" + +#: templates/admin/bills/report.html:39 +msgid "Contact" +msgstr "Contacto" + +#: templates/admin/bills/report.html:40 +#, fuzzy +#| msgid "Due date" +msgid "Close date" +msgstr "Fecha de pago" + +#: templates/admin/bills/report.html:41 +msgid "Base" +msgstr "Base" + +#: templates/admin/bills/report.html:42 templates/bills/microspective.html:111 +#: templates/bills/microspective.html:114 +msgid "VAT" +msgstr "IVA" #: templates/bills/microspective-fee.html:107 msgid "Due date" @@ -427,11 +510,6 @@ msgstr "hrs/cant" msgid "rate/price" msgstr "tarifa/precio" -#: templates/bills/microspective.html:111 -#: templates/bills/microspective.html:114 -msgid "VAT" -msgstr "IVA" - #: templates/bills/microspective.html:114 msgid "taxes" msgstr "impuestos" diff --git a/orchestra/contrib/bills/models.py b/orchestra/contrib/bills/models.py index 2a3e31c5..d7d933ea 100644 --- a/orchestra/contrib/bills/models.py +++ b/orchestra/contrib/bills/models.py @@ -90,6 +90,10 @@ class Bill(models.Model): (AMENDMENTFEE, _("Amendment Fee")), (PROFORMA, _("Pro forma")), ) + AMEND_MAP = { + INVOICE: AMENDMENTINVOICE, + FEE: AMENDMENTFEE, + } number = models.CharField(_("number"), max_length=16, unique=True, blank=True) account = models.ForeignKey('accounts.Account', verbose_name=_("account"), @@ -181,6 +185,24 @@ class Bill(models.Model): return self.EXECUTED return self.BAD_DEBT + def clean(self): + if self.amend_of_id: + errors = {} + if self.type not in self.AMEND_MAP.values(): + errors['amend_of'] = _("Type %s is not an amendment.") % self.get_type_display() + if self.amend_of.account_id != self.account_id: + errors['account'] = _("Amend of related account doesn't match bill account.") + if self.amend_of.is_open: + errors['amend_of'] = _("Related invoice is in open state.") + if self.amend_of.type in self.AMEND_MAP.values(): + errors['amend_of'] = _("Related invoice is an amendment.") + if errors: + raise ValidationError(errors) + elif self.type in self.AMEND_MAP.values(): + raise ValidationError({ + 'amend_of': _("Type %s requires an amend of link.") % self.get_type_display() + }) + def get_total(self): if not self.is_open: return self.total @@ -201,11 +223,7 @@ class Bill(models.Model): return self.type or self.get_class_type() def get_amend_type(self): - amend_map = { - self.INVOICE: self.AMENDMENTINVOICE, - self.FEE: self.AMENDMENTFEE, - } - amend_type = amend_map.get(self.type) + amend_type = self.AMEND_MAP.get(self.type) if amend_type is None: raise TypeError("%s has no associated amend type." % self.type) return amend_type @@ -321,10 +339,17 @@ class Bill(models.Model): subtotals[tax] = (subtotal, round(tax/100*subtotal, 2)) return subtotals + def compute_base(self): + bases = self.lines.annotate( + bases=F('subtotal') + Coalesce(F('sublines__total'), 0) + ) + return round(bases.aggregate(Sum('bases'))['bases__sum'] or 0, 2) + def compute_total(self): totals = self.lines.annotate( - totals=(F('subtotal') + Coalesce(F('sublines__total'), 0)) * (1+F('tax')/100)) - return round(totals.aggregate(Sum('totals'))['totals__sum'], 2) + totals=(F('subtotal') + Coalesce(F('sublines__total'), 0)) * (1+F('tax')/100) + ) + return round(totals.aggregate(Sum('totals'))['totals__sum'] or 0, 2) class Invoice(Bill): @@ -363,7 +388,7 @@ class BillLine(models.Model): subtotal = models.DecimalField(_("subtotal"), max_digits=12, decimal_places=2) tax = models.DecimalField(_("tax"), max_digits=4, decimal_places=2) start_on = models.DateField(_("start")) - end_on = models.DateField(_("end"), null=True) + end_on = models.DateField(_("end"), null=True, blank=True) order = models.ForeignKey(settings.BILLS_ORDER_MODEL, null=True, blank=True, help_text=_("Informative link back to the order"), on_delete=models.SET_NULL) order_billed_on = models.DateField(_("order billed"), null=True, blank=True) diff --git a/orchestra/contrib/bills/templates/admin/bills/report.html b/orchestra/contrib/bills/templates/admin/bills/report.html new file mode 100644 index 00000000..7cb63a83 --- /dev/null +++ b/orchestra/contrib/bills/templates/admin/bills/report.html @@ -0,0 +1,60 @@ +{% load i18n utils %} + + +
+{% trans "Number" %} | +{% trans "VAT number" %} | +{% trans "Contact" %} | +{% trans "Close date" %} | +{% trans "Base" %} | +{% trans "VAT" %} | +{% trans "Total" %} | +
---|---|---|---|---|---|---|
{{ bill.number }} | +{{ bill.buyer.vat }} | +{{ bill.buyer.get_name }} | +{{ bill.closed_on|date }} | + {% with base=bill.compute_base total=bill.compute_total %} +{{ base }} &{{ currency }}; | +{{ total|sub:base }} &{{ currency }}; | +{{ total }} &{{ currency }}; | + {% endwith %} +