Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Open sidebar
chris
repanier
Commits
6c2e7850
Commit
6c2e7850
authored
Apr 13, 2017
by
Patrick
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
New version in progress
parent
0df4f789
Changes
70
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
70 changed files
with
2972 additions
and
2703 deletions
+2972
-2703
mysite/common_settings.py
mysite/common_settings.py
+26
-25
repanier/admin/admin_filter.py
repanier/admin/admin_filter.py
+2
-2
repanier/admin/box.py
repanier/admin/box.py
+11
-4
repanier/admin/configuration.py
repanier/admin/configuration.py
+1
-1
repanier/admin/customer.py
repanier/admin/customer.py
+26
-3
repanier/admin/forms.py
repanier/admin/forms.py
+2
-3
repanier/admin/lut.py
repanier/admin/lut.py
+1
-1
repanier/admin/offeritem.py
repanier/admin/offeritem.py
+4
-3
repanier/admin/permanence_done.py
repanier/admin/permanence_done.py
+202
-179
repanier/admin/permanence_in_preparation.py
repanier/admin/permanence_in_preparation.py
+147
-187
repanier/admin/producer.py
repanier/admin/producer.py
+51
-8
repanier/admin/product.py
repanier/admin/product.py
+47
-23
repanier/admin/purchase.py
repanier/admin/purchase.py
+1
-1
repanier/admin/rule_of_3_per_product.py
repanier/admin/rule_of_3_per_product.py
+1
-2
repanier/admin/staff.py
repanier/admin/staff.py
+7
-0
repanier/apps.py
repanier/apps.py
+5
-3
repanier/cms_menus.py
repanier/cms_menus.py
+2
-2
repanier/const.py
repanier/const.py
+4
-4
repanier/email/email_invoice.py
repanier/email/email_invoice.py
+12
-19
repanier/email/email_offer.py
repanier/email/email_offer.py
+12
-18
repanier/email/email_order.py
repanier/email/email_order.py
+60
-115
repanier/fields/RepanierMoneyField.py
repanier/fields/RepanierMoneyField.py
+1
-1
repanier/locale/fr/LC_MESSAGES/django.mo
repanier/locale/fr/LC_MESSAGES/django.mo
+0
-0
repanier/locale/fr/LC_MESSAGES/django.po
repanier/locale/fr/LC_MESSAGES/django.po
+736
-727
repanier/lock_exemple.py
repanier/lock_exemple.py
+74
-60
repanier/management/commands/delete_permanence.py
repanier/management/commands/delete_permanence.py
+1
-1
repanier/management/commands/recalculate_order_amount.py
repanier/management/commands/recalculate_order_amount.py
+59
-23
repanier/models/configuration.py
repanier/models/configuration.py
+7
-3
repanier/models/customer.py
repanier/models/customer.py
+14
-20
repanier/models/deliveryboard.py
repanier/models/deliveryboard.py
+19
-20
repanier/models/invoice.py
repanier/models/invoice.py
+128
-97
repanier/models/lut.py
repanier/models/lut.py
+1
-1
repanier/models/offeritem.py
repanier/models/offeritem.py
+18
-22
repanier/models/permanence.py
repanier/models/permanence.py
+442
-268
repanier/models/producer.py
repanier/models/producer.py
+47
-49
repanier/models/product.py
repanier/models/product.py
+32
-0
repanier/models/purchase.py
repanier/models/purchase.py
+55
-49
repanier/picture/fields.py
repanier/picture/fields.py
+1
-1
repanier/rest/permanence.py
repanier/rest/permanence.py
+41
-43
repanier/task/task_invoice.py
repanier/task/task_invoice.py
+108
-111
repanier/task/task_order.py
repanier/task/task_order.py
+8
-24
repanier/task/task_producer.py
repanier/task/task_producer.py
+98
-116
repanier/templates/404.html
repanier/templates/404.html
+1
-0
repanier/templates/admin/actions.html
repanier/templates/admin/actions.html
+18
-0
repanier/templates/admin/base.html
repanier/templates/admin/base.html
+4
-0
repanier/templates/admin/producer_change_list.html
repanier/templates/admin/producer_change_list.html
+0
-6
repanier/templates/admin/purchase_change_list.html
repanier/templates/admin/purchase_change_list.html
+0
-6
repanier/templates/repanier/customer_invoice_form.html
repanier/templates/repanier/customer_invoice_form.html
+32
-27
repanier/templates/repanier/order_form.html
repanier/templates/repanier/order_form.html
+2
-2
repanier/templates/repanier/producer_invoice_form.html
repanier/templates/repanier/producer_invoice_form.html
+55
-36
repanier/templatetags/repanier_tags.py
repanier/templatetags/repanier_tags.py
+1
-1
repanier/tools.py
repanier/tools.py
+98
-116
repanier/urls.py
repanier/urls.py
+5
-3
repanier/views/basket_message_form_ajax.py
repanier/views/basket_message_form_ajax.py
+25
-6
repanier/views/customer_invoice_class.py
repanier/views/customer_invoice_class.py
+2
-2
repanier/views/customer_product_description_ajax.py
repanier/views/customer_product_description_ajax.py
+3
-7
repanier/views/display_status_ajax.py
repanier/views/display_status_ajax.py
+0
-4
repanier/views/is_into_offer_ajax.py
repanier/views/is_into_offer_ajax.py
+28
-0
repanier/views/like_ajax.py
repanier/views/like_ajax.py
+1
-1
repanier/views/order_class.py
repanier/views/order_class.py
+1
-1
repanier/views/order_init_ajax.py
repanier/views/order_init_ajax.py
+3
-3
repanier/views/producer_invoice_class.py
repanier/views/producer_invoice_class.py
+2
-2
repanier/views/send_mail_to_coordinators_view.py
repanier/views/send_mail_to_coordinators_view.py
+4
-9
repanier/xlsx/widget.py
repanier/xlsx/widget.py
+7
-7
repanier/xlsx/xlsx_invoice.py
repanier/xlsx/xlsx_invoice.py
+2
-57
repanier/xlsx/xlsx_offer.py
repanier/xlsx/xlsx_offer.py
+0
-14
repanier/xlsx/xlsx_order.py
repanier/xlsx/xlsx_order.py
+143
-87
repanier/xlsx/xlsx_product.py
repanier/xlsx/xlsx_product.py
+0
-12
repanier/xlsx/xlsx_purchase.py
repanier/xlsx/xlsx_purchase.py
+8
-28
repanier/xlsx/xlsx_stock.py
repanier/xlsx/xlsx_stock.py
+13
-27
No files found.
mysite/common_settings.py
View file @
6c2e7850
...
...
@@ -512,34 +512,34 @@ CMS_TEMPLATES = (
(
'cms_bootstrap_subpage.html'
,
gettext
(
"Bootstrap page with menu on left"
))
)
if
DJANGO_SETTINGS_LANGUAGE
==
'fr'
:
#
if DJANGO_SETTINGS_LANGUAGE == 'fr':
LANGUAGE_CODE
=
'fr'
LANGUAGES
=
[
(
'fr'
,
get_language_info
(
'fr'
)[
'name_local'
]),
]
CMS_LANGUAGES
=
{
SITE_ID
:
[
{
'code'
:
'fr'
,
'name'
:
get_language_info
(
'fr'
)[
'name'
],
'public'
:
True
,
'hide_untranslated'
:
False
,
},
]
}
PARLER_DEFAULT_LANGUAGE_CODE
=
LANGUAGE_CODE
PARLER_LANGUAGES
=
{
SITE_ID
:
(
{
'code'
:
LANGUAGE_CODE
,},
),
'default'
:
{
'fallbacks'
:
[
LANGUAGE_CODE
],
'hide_untranslated'
:
False
,
LANGUAGE_CODE
=
'fr'
LANGUAGES
=
[
(
'fr'
,
get_language_info
(
'fr'
)[
'name_local'
]),
]
CMS_LANGUAGES
=
{
SITE_ID
:
[
{
'code'
:
'fr'
,
'name'
:
get_language_info
(
'fr'
)[
'name'
],
'public'
:
True
,
'hide_untranslated'
:
False
,
},
}
]
}
PARLER_DEFAULT_LANGUAGE_CODE
=
LANGUAGE_CODE
PARLER_LANGUAGES
=
{
SITE_ID
:
(
{
'code'
:
LANGUAGE_CODE
,},
),
'default'
:
{
'fallbacks'
:
[
LANGUAGE_CODE
],
'hide_untranslated'
:
False
,
},
}
el
if
DJANGO_SETTINGS_LANGUAGE
==
'es'
:
if
DJANGO_SETTINGS_LANGUAGE
==
'es'
:
LANGUAGE_CODE
=
'es'
LANGUAGES
=
[
...
...
@@ -645,6 +645,7 @@ elif DJANGO_SETTINGS_LANGUAGE == 'fr-en':
},
}
DJANGO_SETTINGS_MULTIPLE_LANGUAGE
=
len
(
LANGUAGES
)
>
1
##################### DJANGOCMS-CASCADE
CMSPLUGIN_CASCADE_PLUGINS
=
(
'cmsplugin_cascade.generic'
,
...
...
repanier/admin/admin_filter.py
View file @
6c2e7850
...
...
@@ -189,7 +189,7 @@ class PurchaseFilterByPermanence(SimpleListFilter):
def
lookups
(
self
,
request
,
model_admin
):
permanence_id
=
request
.
GET
.
get
(
'permanence'
,
None
)
if
permanence_id
is
None
:
return
[(
p
.
id
,
p
.
get_permanence_display
(
with_status
=
False
))
for
p
in
return
[(
p
.
id
,
p
.
get_permanence_display
())
for
p
in
Permanence
.
objects
.
filter
(
status__in
=
[
PERMANENCE_OPENED
,
PERMANENCE_CLOSED
,
PERMANENCE_SEND
])
]
else
:
...
...
@@ -208,7 +208,7 @@ class OfferItemSendFilterByPermanence(SimpleListFilter):
parameter_name
=
'permanence'
def
lookups
(
self
,
request
,
model_admin
):
return
[(
p
.
id
,
p
.
get_permanence_display
(
with_status
=
False
))
for
p
in
return
[(
p
.
id
,
p
.
get_permanence_display
())
for
p
in
Permanence
.
objects
.
filter
(
status
=
PERMANENCE_SEND
)
]
...
...
repanier/admin/box.py
View file @
6c2e7850
...
...
@@ -4,6 +4,7 @@ from __future__ import unicode_literals
from
os
import
sep
as
os_sep
from
django
import
forms
from
django.conf
import
settings
from
django.contrib
import
admin
from
django.contrib
import
messages
from
django.contrib.admin
import
TabularInline
...
...
@@ -180,6 +181,12 @@ class BoxAdmin(TranslatableAdmin):
def
has_change_permission
(
self
,
request
,
box
=
None
):
return
self
.
has_delete_permission
(
request
,
box
)
def
get_list_display
(
self
,
request
):
if
settings
.
DJANGO_SETTINGS_MULTIPLE_LANGUAGE
:
return
(
'is_into_offer'
,
'get_long_name'
,
'language_column'
)
else
:
return
(
'is_into_offer'
,
'get_long_name'
)
def
flip_flop_select_for_offer_status
(
self
,
request
,
queryset
):
task_box
.
flip_flop_is_into_offer
(
queryset
)
...
...
@@ -191,17 +198,17 @@ class BoxAdmin(TranslatableAdmin):
user_message
=
_
(
"Action canceled by the user."
)
user_message_level
=
messages
.
INFO
self
.
message_user
(
request
,
user_message
,
user_message_level
)
return
None
box
=
queryset
.
order_by
(
'?'
).
first
()
return
box
=
queryset
.
first
()
if
box
is
None
:
user_message
=
_
(
"Action canceled by the system."
)
user_message_level
=
messages
.
ERROR
self
.
message_user
(
request
,
user_message
,
user_message_level
)
return
None
return
if
'apply'
in
request
.
POST
:
user_message
,
user_message_level
=
task_box
.
admin_duplicate
(
queryset
)
self
.
message_user
(
request
,
user_message
,
user_message_level
)
return
None
return
return
render
(
request
,
'repanier/confirm_admin_duplicate_box.html'
,
{
...
...
repanier/admin/configuration.py
View file @
6c2e7850
...
...
@@ -117,7 +117,7 @@ class ConfigurationAdmin(TranslatableAdmin):
permanence
=
Permanence
.
objects
.
all
().
order_by
(
'?'
)
is_coordinator
=
request
.
user
.
is_superuser
or
request
.
user
.
is_staff
if
is_coordinator
or
permanence
.
fir
st
()
is
None
:
if
is_coordinator
or
not
permanence
.
exi
st
s
():
return
[]
else
:
return
[
'bank_account'
]
repanier/admin/customer.py
View file @
6c2e7850
...
...
@@ -14,20 +14,23 @@ from django.contrib.auth import get_user_model
from
django.contrib.auth.models
import
User
from
django.db.models
import
Q
from
django.forms
import
Textarea
from
django.http
import
HttpResponse
from
django.utils
import
timezone
from
django.utils.text
import
slugify
from
django.utils.translation
import
ugettext_lazy
as
_
from
import_export
import
resources
,
fields
from
import_export.admin
import
ImportExportMixin
from
import_export.formats.base_formats
import
XLS
from
import_export.widgets
import
CharWidget
import
repanier.apps
from
repanier.const
import
EMPTY_STRING
,
ORDER_GROUP
,
INVOICE_GROUP
,
\
COORDINATION_GROUP
,
DECIMAL_ONE
,
TWO_DECIMALS
from
repanier.models
import
Customer
,
LUT_DeliveryPoint
from
repanier.xlsx
import
xlsx_invoice
from
repanier.xlsx.widget
import
IdWidget
,
OneToOneWidget
,
\
DecimalBooleanWidget
,
ZeroDecimalsWidget
,
TwoMoneysWidget
,
TranslatedForeignKeyWidget
,
DateWidgetExcel
from
repanier.xlsx.extended_formats
import
XLSX_OPENPYXL_1_8_6
from
repanier.xlsx.xlsx_invoice
import
export_invoice
class
UserDataForm
(
forms
.
ModelForm
):
...
...
@@ -215,8 +218,20 @@ class CustomerResource(resources.ModelResource):
def
create__customer_action
(
year
):
def
action
(
modeladmin
,
request
,
customer_qs
):
# return xlsx_purchase.admin_export_year_by_customer(year, customer_qs)
return
xlsx_invoice
.
admin_export_customer_invoices_report
(
request
,
customer_qs
,
year
)
# To the customer we speak of "invoice".
# This is the detail of the invoice, i.e. sold products
wb
=
None
for
customer
in
customer_qs
:
wb
=
export_invoice
(
year
=
year
,
customer
=
customer
,
wb
=
wb
,
sheet_name
=
slugify
(
customer
))
if
wb
is
not
None
:
response
=
HttpResponse
(
content_type
=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
response
[
'Content-Disposition'
]
=
"attachment; filename={0}-{1}.xlsx"
.
format
(
"%s %s"
%
(
_
(
'Invoice'
),
year
),
repanier
.
apps
.
REPANIER_SETTINGS_GROUP_NAME
)
wb
.
save
(
response
)
return
response
return
name
=
"export_producer_%d"
%
(
year
,)
return
(
name
,
(
action
,
name
,
_
(
"Export purchases of %s"
)
%
(
year
,)))
...
...
@@ -294,6 +309,14 @@ class CustomerWithUserDataAdmin(ImportExportMixin, admin.ModelAdmin):
actions
.
update
(
OrderedDict
(
create__customer_action
(
y
)
for
y
in
[
this_year
,
this_year
-
1
,
this_year
-
2
]))
return
actions
def
get_list_display
(
self
,
request
):
if
repanier
.
apps
.
REPANIER_SETTINGS_INVOICE
:
return
(
'short_basket_name'
,
'get_balance'
,
'may_order'
,
'long_basket_name'
,
'phone1'
,
'get_email'
,
'get_last_login'
,
'valid_email'
)
else
:
return
(
'short_basket_name'
,
'may_order'
,
'long_basket_name'
,
'phone1'
,
'get_email'
,
'get_last_login'
,
'valid_email'
)
def
get_fieldsets
(
self
,
request
,
customer
=
None
):
fields_basic
=
[
(
'short_basket_name'
,
'long_basket_name'
,
'language'
),
...
...
repanier/admin/forms.py
View file @
6c2e7850
...
...
@@ -35,9 +35,8 @@ class CloseAndSendOrderForm(forms.Form):
class
GeneratePermanenceForm
(
forms
.
Form
):
repeat_counter
=
forms
.
DecimalField
(
label
=
_
(
"Number of permanence(s)"
),
min_value
=
0
,
max_value
=
54
,
decimal_places
=
0
)
repeat_step
=
forms
.
DecimalField
(
label
=
_
(
"Number of week(s) between two permanences"
),
min_value
=
0
,
max_value
=
12
,
decimal_places
=
0
)
repeat_counter
=
forms
.
IntegerField
(
label
=
_
(
"Number of permanence(s)"
),
min_value
=
0
,
max_value
=
54
)
repeat_step
=
forms
.
IntegerField
(
label
=
_
(
"Number of week(s) between two permanences"
),
min_value
=
0
,
max_value
=
12
)
def
__init__
(
self
,
*
args
,
**
kwargs
):
self
.
request
=
kwargs
.
pop
(
'request'
,
None
)
...
...
repanier/admin/lut.py
View file @
6c2e7850
...
...
@@ -145,7 +145,7 @@ class LUTDeliveryPointDataForm(TranslatableModelForm):
# also responsible for collecting the payments.
# The LUT_DeliveryPoint.price_list_multiplier will be used when invoicing the consumer responsible
# The link between the customer invoice and this customer responsible is made with
# CustomerInvoice.customer_
who_pays
# CustomerInvoice.customer_
charged
Customer
.
objects
.
filter
(
delivery_point
=
self
.
instance
.
id
).
update
(
price_list_multiplier
=
DECIMAL_ONE
)
return
instance
...
...
repanier/admin/offeritem.py
View file @
6c2e7850
...
...
@@ -163,6 +163,7 @@ class OfferItemClosedAdmin(admin.ModelAdmin):
def
save_model
(
self
,
request
,
offer_item
,
form
,
change
):
super
(
OfferItemClosedAdmin
,
self
).
save_model
(
request
,
offer_item
,
form
,
change
)
offer_item
.
product
.
stock
=
offer_item
.
stock
offer_item
.
product
.
save
(
update_fields
=
[
'stock'
])
update_offer_item
(
product_id
=
offer_item
.
product_id
)
if
offer_item
.
product_id
is
not
None
:
offer_item
.
product
.
stock
=
offer_item
.
stock
offer_item
.
product
.
save
(
update_fields
=
[
'stock'
])
update_offer_item
(
product_id
=
offer_item
.
product_id
)
repanier/admin/permanence_done.py
View file @
6c2e7850
This diff is collapsed.
Click to expand it.
repanier/admin/permanence_in_preparation.py
View file @
6c2e7850
This diff is collapsed.
Click to expand it.
repanier/admin/producer.py
View file @
6c2e7850
...
...
@@ -7,7 +7,10 @@ from django import forms
from
django.conf
import
settings
from
django.conf.urls
import
url
from
django.contrib
import
admin
from
django.db.models
import
Q
from
django.http
import
HttpResponse
from
django.utils
import
timezone
from
django.utils.text
import
slugify
from
django.utils.translation
import
ugettext_lazy
as
_
from
import_export
import
resources
,
fields
from
import_export.admin
import
ImportExportMixin
...
...
@@ -21,10 +24,13 @@ from repanier.models import Permanence, Product, \
Producer
from
repanier.tools
import
producer_web_services_activated
,
\
update_offer_item
from
repanier.xlsx
import
xlsx_stock
,
xlsx_invoice
,
xlsx_product
from
repanier.xlsx.widget
import
IdWidget
,
TwoDecimalsWidget
,
\
DecimalBooleanWidget
,
TwoMoneysWidget
,
DateWidgetExcel
from
repanier.xlsx.extended_formats
import
XLSX_OPENPYXL_1_8_6
from
repanier.xlsx.views
import
import_xslx_view
from
repanier.xlsx.xlsx_invoice
import
export_invoice
from
repanier.xlsx.xlsx_product
import
export_customer_prices
from
repanier.xlsx.xlsx_stock
import
handle_uploaded_stock
,
export_producer_stock
try
:
from
urllib.parse
import
parse_qsl
...
...
@@ -89,8 +95,20 @@ class ProducerResource(resources.ModelResource):
def
create__producer_action
(
year
):
def
action
(
modeladmin
,
request
,
producer_qs
):
# return xlsx_purchase.admin_export_year_by_producer(year, queryset)
return
xlsx_invoice
.
admin_export_producer_invoices_report
(
request
,
producer_qs
,
year
)
# To the producer we speak of "payment".
# This is the detail of the payment to the producer, i.e. received products
wb
=
None
for
producer
in
producer_qs
:
wb
=
export_invoice
(
year
=
year
,
producer
=
producer
,
wb
=
wb
,
sheet_name
=
slugify
(
producer
))
if
wb
is
not
None
:
response
=
HttpResponse
(
content_type
=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
response
[
'Content-Disposition'
]
=
"attachment; filename={0}-{1}.xlsx"
.
format
(
"%s %s"
%
(
_
(
'Payment'
),
year
),
repanier
.
apps
.
REPANIER_SETTINGS_GROUP_NAME
)
wb
.
save
(
response
)
return
response
return
name
=
"export_producer_%d"
%
(
year
,)
return
(
name
,
(
action
,
name
,
_
(
"Export purchases of %s"
)
%
(
year
,)))
...
...
@@ -216,7 +234,7 @@ class ProducerAdmin(ImportExportMixin, admin.ModelAdmin):
actions
=
[
'export_xlsx_customer_prices'
,
]
change_list_template
=
'admin/producer_change_list.html'
#
change_list_template = 'admin/producer_change_list.html'
def
has_delete_permission
(
self
,
request
,
producer
=
None
):
if
request
.
user
.
groups
.
filter
(
...
...
@@ -247,18 +265,40 @@ class ProducerAdmin(ImportExportMixin, admin.ModelAdmin):
return
my_urls
+
urls
def
export_xlsx_customer_prices
(
self
,
request
,
producer_qs
):
return
xlsx_product
.
admin_export_customer_prices
(
producer_qs
,
producer_prices
=
False
)
wb
=
export_customer_prices
(
producer_qs
=
producer_qs
,
wb
=
None
,
producer_prices
=
False
)
if
wb
is
not
None
:
response
=
HttpResponse
(
content_type
=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
response
[
'Content-Disposition'
]
=
"attachment; filename={0}.xlsx"
.
format
(
slugify
(
_
(
"Products"
))
)
wb
.
save
(
response
)
return
response
else
:
return
export_xlsx_customer_prices
.
short_description
=
_
(
"Export products of selected producer(s) as XSLX file at customer's prices"
)
def
export_xlsx_stock
(
self
,
request
):
return
xlsx_stock
.
admin_export
(
self
,
Producer
.
objects
.
all
())
# return xlsx_stock.admin_export(self, Producer.objects.all())
wb
=
export_producer_stock
(
producers
=
Producer
.
objects
.
filter
(
Q
(
manage_replenishment
=
True
)
|
Q
(
manage_production
=
True
)
).
order_by
(
"short_profile_name"
),
wb
=
None
)
if
wb
is
not
None
:
response
=
HttpResponse
(
content_type
=
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)
response
[
'Content-Disposition'
]
=
"attachment; filename={0}.xlsx"
.
format
(
slugify
(
_
(
"Current stock"
))
)
wb
.
save
(
response
)
return
response
else
:
return
export_xlsx_stock
.
short_description
=
_
(
"Export stock to a xlsx file"
)
def
import_xlsx_stock
(
self
,
request
):
return
xlsx_stock
.
admin_import
(
self
,
admin
,
request
,
Producer
.
objects
.
all
(),
action
=
'import_xlsx_stock'
)
return
import_xslx_view
(
self
,
admin
,
request
,
Producer
.
objects
.
all
(),
_
(
"Import stock"
),
handle_uploaded_stock
,
action
=
'import_xlsx_stock'
)
# return xlsx_stock.admin_import(self, admin, request, Producer.objects.all(), action='import_xlsx_stock')
import_xlsx_stock
.
short_description
=
_
(
"Import stock from a xlsx file"
)
...
...
@@ -269,7 +309,10 @@ class ProducerAdmin(ImportExportMixin, admin.ModelAdmin):
return
actions
def
get_list_display
(
self
,
request
):
return
(
'__str__'
,
'get_products'
,
'get_balance'
,
'phone1'
,
'email'
)
if
repanier
.
apps
.
REPANIER_SETTINGS_INVOICE
:
return
(
'__str__'
,
'get_products'
,
'get_balance'
,
'phone1'
,
'email'
)
else
:
return
(
'__str__'
,
'get_products'
,
'phone1'
,
'email'
)
def
get_fieldsets
(
self
,
request
,
producer
=
None
):
fields_basic
=
[
...
...
repanier/admin/product.py
View file @
6c2e7850
...
...
@@ -276,7 +276,7 @@ class ProductDataForm(TranslatableModelForm):
class
ProductAdmin
(
ImportExportMixin
,
TranslatableAdmin
):
form
=
ProductDataForm
resource_class
=
ProductResource
list_display
=
(
'is_into_offer'
,
'producer'
,
'department_for_customer'
,
'get_long_name'
,
'producer_unit_price'
,
list_display
=
(
'producer'
,
'department_for_customer'
,
'get_long_name'
,
'get_is_into_offer'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
,
'stock'
)
list_display_links
=
(
'get_long_name'
,)
readonly_fields
=
(
'is_updated_on'
,)
...
...
@@ -297,7 +297,7 @@ class ProductAdmin(ImportExportMixin, TranslatableAdmin):
'limit_order_quantity_to_stock'
,
ProductFilterByVatLevel
)
actions
=
[
'flip_flop_select_for_offer_status'
,
#
'flip_flop_select_for_offer_status',
'duplicate_product'
]
...
...
@@ -328,13 +328,13 @@ class ProductAdmin(ImportExportMixin, TranslatableAdmin):
user_message
=
_
(
"Action canceled by the user."
)
user_message_level
=
messages
.
INFO
self
.
message_user
(
request
,
user_message
,
user_message_level
)
return
None
product
=
queryset
.
order_by
(
'?'
).
first
()
return
product
=
queryset
.
first
()
if
product
is
None
or
product
.
is_box
:
user_message
=
_
(
"Action canceled by the system."
)
user_message_level
=
messages
.
ERROR
self
.
message_user
(
request
,
user_message
,
user_message_level
)
return
None
return
if
'apply'
in
request
.
POST
:
if
"producers"
in
request
.
POST
:
producers
=
request
.
POST
.
getlist
(
"producers"
)
...
...
@@ -343,11 +343,11 @@ class ProductAdmin(ImportExportMixin, TranslatableAdmin):
if
producer
is
not
None
:
user_message
,
user_message_level
=
task_product
.
admin_duplicate
(
queryset
,
producer
)
self
.
message_user
(
request
,
user_message
,
user_message_level
)
return
None
return
user_message
=
_
(
"You must select one and only one producer."
)
user_message_level
=
messages
.
ERROR
self
.
message_user
(
request
,
user_message
,
user_message_level
)
return
None
return
return
render
(
request
,
'repanier/confirm_admin_duplicate_product.html'
,
{
...
...
@@ -367,27 +367,51 @@ class ProductAdmin(ImportExportMixin, TranslatableAdmin):
producer
=
producer_queryset
.
first
()
else
:
producer
=
None
if
producer
is
not
None
:
if
producer
.
producer_pre_opening
:
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'is_into_offer'
,
'producer'
,
'department_for_customer'
,
'get_long_name'
,
'language_column'
,
'producer_unit_price'
,
'stock'
)
elif
producer
.
manage_replenishment
or
producer
.
manage_production
:
if
settings
.
DJANGO_SETTINGS_MULTIPLE_LANGUAGE
:
if
producer
is
not
None
:
if
producer
.
producer_pre_opening
:
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'producer'
,
'department_for_customer'
,
'get_is_into_offer'
,
'get_long_name'
,
'language_column'
,
'producer_unit_price'
,
'stock'
)
elif
producer
.
manage_replenishment
or
producer
.
manage_production
:
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'producer'
,
'department_for_customer'
,
'get_is_into_offer'
,
'get_long_name'
,
'language_column'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
,
'stock'
)
else
:
self
.
list_editable
=
(
'producer_unit_price'
,)
return
(
'producer'
,
'department_for_customer'
,
'get_is_into_offer'
,
'get_long_name'
,
'language_column'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
)
else
:
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'is_into_offer'
,
'producer'
,
'department_for_customer'
,
'get_long_name'
,
'language_column'
,
return
(
'producer'
,
'department_for_customer'
,
'get_is_into_offer'
,
'get_long_name'
,
'language_column'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
,
'stock'
)
else
:
if
producer
is
not
None
:
if
producer
.
producer_pre_opening
:
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'producer'
,
'department_for_customer'
,
'get_is_into_offer'
,
'get_long_name'
,
'producer_unit_price'
,
'stock'
)
elif
producer
.
manage_replenishment
or
producer
.
manage_production
:
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'producer'
,
'department_for_customer'
,
'get_is_into_offer'
,
'get_long_name'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
,
'stock'
)
else
:
self
.
list_editable
=
(
'producer_unit_price'
,)
return
(
'producer'
,
'department_for_customer'
,
'get_is_into_offer'
,
'get_long_name'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
)
else
:
self
.
list_editable
=
(
'producer_unit_price'
,)
return
(
'is_into_offer'
,
'producer'
,
'department_for_customer'
,
'get_
long_name'
,
'language_column
'
,
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'producer'
,
'department_for_customer'
,
'get_
is_into_offer'
,
'get_long_name
'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
)
else
:
self
.
list_editable
=
(
'producer_unit_price'
,
'stock'
)
return
(
'is_into_offer'
,
'producer'
,
'department_for_customer'
,
'get_long_name'
,
'language_column'
,
'producer_unit_price'
,
'get_customer_alert_order_quantity'
,
'stock'
)
'get_customer_alert_order_quantity'
,
'stock'
)
def
get_form
(
self
,
request
,
product
=
None
,
**
kwargs
):
department_for_customer_id
=
None
...
...
repanier/admin/purchase.py
View file @
6c2e7850
...
...
@@ -157,7 +157,7 @@ class PurchaseAdmin(ExportMixin, admin.ModelAdmin):
list_display_links
=
(
'offer_item'
,)
search_fields
=
(
'offer_item__translations__long_name'
,)
actions
=
[]
change_list_template
=
'admin/purchase_change_list.html'
#
change_list_template = 'admin/purchase_change_list.html'
def
__init__
(
self
,
model
,
admin_site
):
super
(
PurchaseAdmin
,
self
).
__init__
(
model
,
admin_site
)
...
...
repanier/admin/rule_of_3_per_product.py
View file @
6c2e7850
...
...
@@ -412,8 +412,7 @@ class OfferItemSendAdmin(admin.ModelAdmin):
recalculate_order_amount
(
permanence_id
=
offer_item
.
permanence_id
,
offer_item_queryset
=
OfferItem
.
objects
.
filter
(
id
=
offer_item
.
id
).
order_by
(
'?'
),
send_to_producer
=
False
offer_item_qs
=
OfferItem
.
objects
.
filter
(
id
=
offer_item
.
id
).
order_by
(
'?'
)
)
if
offer_item
.
manage_replenishment
:
...
...
repanier/admin/staff.py
View file @
6c2e7850
...
...
@@ -4,6 +4,7 @@ from __future__ import unicode_literals
import
uuid
from
django
import
forms
from
django.conf
import
settings
from
django.contrib.auth
import
get_user_model
from
django.utils.translation
import
ugettext_lazy
as
_
from
easy_select2
import
apply_select2
...
...
@@ -141,6 +142,12 @@ class StaffWithUserDataAdmin(LUTAdmin):
def
has_change_permission
(
self
,
request
,
staff
=
None
):
return
self
.
has_add_permission
(
request
)
def
get_list_display
(
self
,
request
):
if
settings
.
DJANGO_SETTINGS_MULTIPLE_LANGUAGE
:
return
(
'user'
,
'language_column'
,
'long_name'
,
'customer_responsible'
,
'get_customer_phone1'
)
else
:
return
(
'user'
,
'long_name'
,
'customer_responsible'
,
'get_customer_phone1'
)
def
get_form
(
self
,
request
,
obj
=
None
,
**
kwargs
):
form
=
super
(
StaffWithUserDataAdmin
,
self
).
get_form
(
request
,
obj
,
**
kwargs
)
username_field
=
form
.
base_fields
[
'username'
]
...
...
repanier/apps.py
View file @
6c2e7850
...
...
@@ -3,6 +3,7 @@ from __future__ import unicode_literals
import
time
import
sys
from
django.apps
import
AppConfig
from
django.conf
import
settings
from
django.db
import
connection
...
...
@@ -12,9 +13,9 @@ from django.utils.translation import ugettext_lazy as _
REPANIER_SETTINGS_CONFIG
=
None
REPANIER_SETTINGS_TEST_MODE
=
None
REPANIER_SETTINGS_GROUP_NAME
=
None
REPANIER_SETTINGS_PERMANENCE_NAME
=
None
REPANIER_SETTINGS_PERMANENCES_NAME
=
None
REPANIER_SETTINGS_PERMANENCE_ON_NAME
=
None
REPANIER_SETTINGS_PERMANENCE_NAME
=
_
(
"Permanence"
)
REPANIER_SETTINGS_PERMANENCES_NAME
=
_
(
"Permanences"
)
REPANIER_SETTINGS_PERMANENCE_ON_NAME
=
_
(
"Permanence on "
)
REPANIER_SETTINGS_MAX_WEEK_WO_PARTICIPATION
=
None
REPANIER_SETTINGS_SEND_OPENING_MAIL_TO_CUSTOMER
=
None
REPANIER_SETTINGS_SEND_ORDER_MAIL_TO_CUSTOMER
=
None
...
...
@@ -43,6 +44,7 @@ REPANIER_SETTINGS_CURRENCY_XLSX = None
REPANIER_SETTINGS_HOME_SITE
=
None
REPANIER_SETTINGS_TRANSPORT
=
None
REPANIER_SETTINGS_MIN_TRANSPORT
=
None
DJANGO_IS_MIGRATION_RUNNING
=
'makemigrations'
in
sys
.
argv
or
'migrate'
in
sys
.
argv
class
RepanierSettings
(
AppConfig
):
...
...
repanier/cms_menus.py
View file @
6c2e7850
...
...
@@ -34,7 +34,7 @@ class PermanenceMenu(Menu):
submenu_id
=
master_id
separator
=
False
permanence_board_set
=
PermanenceBoard
.
objects
.
filter
(
permanence__status__lte
=
PERMANENCE_WAIT_FOR_
DONE
).
only
(
permanence_board_set
=
PermanenceBoard
.
objects
.
filter
(
permanence__status__lte
=
PERMANENCE_WAIT_FOR_
INVOICED
).
only
(
"id"
).
order_by
(
'?'
)
if
permanence_board_set
.
exists
():
submenu_id
+=
1
...
...
@@ -76,7 +76,7 @@ class PermanenceMenu(Menu):
break
if
displayed_permanence_counter
<
4
:
max_counter
=
4
-
displayed_permanence_counter
for
permanence
in
Permanence
.
objects
.
filter
(
status__in
=
[
PERMANENCE_
DONE
,
PERMANENCE_ARCHIVED
])
\
for
permanence
in
Permanence
.
objects
.
filter
(
status__in
=
[
PERMANENCE_
INVOICED
,
PERMANENCE_ARCHIVED
])
\
.
only
(
"id"
,
"permanence_date"
)
\
.
order_by
(
'-permanence_date'
):
if
permanence
.
permanence_date
>=
(
...
...
repanier/const.py
View file @
6c2e7850
...
...
@@ -57,9 +57,9 @@ PERMANENCE_WAIT_FOR_CLOSED = '350'
PERMANENCE_CLOSED
=
'370'
PERMANENCE_WAIT_FOR_SEND
=
'400'
PERMANENCE_SEND
=
'500'
PERMANENCE_WAIT_FOR_
DONE
=
'600'
PERMANENCE_WAIT_FOR_
INVOICED
=
'600'
PERMANENCE_INVOICES_VALIDATION_FAILED
=
'700'
PERMANENCE_
DONE
=
'800'
PERMANENCE_
INVOICED
=
'800'
PERMANENCE_ARCHIVED
=
'900'
LUT_PERMANENCE_STATUS
=
(
...
...
@@ -73,9 +73,9 @@ LUT_PERMANENCE_STATUS = (
(
PERMANENCE_CLOSED
,
_
(
'orders closed'
)),
(
PERMANENCE_WAIT_FOR_SEND
,
_
(
'wait for send'
)),
(
PERMANENCE_SEND
,
_
(
'orders send to producers'
)),
(
PERMANENCE_WAIT_FOR_
DONE
,
_
(
'wait for done'
)),
(
PERMANENCE_WAIT_FOR_
INVOICED
,
_
(
'wait for done'
)),
(
PERMANENCE_INVOICES_VALIDATION_FAILED
,
_
(
'invoices validation test failed'
)),
(
PERMANENCE_
DONE
,
_
(
'done
'
)),
(
PERMANENCE_
INVOICED
,
_
(
'invoiced
'
)),
(
PERMANENCE_ARCHIVED
,
_
(
'archived'
))
)
...
...
repanier/email/email_invoice.py
View file @
6c2e7850
...
...
@@ -38,12 +38,9 @@ def send_invoice(permanence_id):
if
Purchase
.
objects
.
filter
(