Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
R
repanier
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
chris
repanier
Commits
0157185d
Commit
0157185d
authored
Apr 19, 2017
by
Patrick
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Work in progress
parent
8ba5667f
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
189 additions
and
98 deletions
+189
-98
repanier/admin/admin_filter.py
repanier/admin/admin_filter.py
+1
-1
repanier/admin/product.py
repanier/admin/product.py
+4
-1
repanier/admin/purchase.py
repanier/admin/purchase.py
+1
-1
repanier/const.py
repanier/const.py
+30
-2
repanier/models/offeritem.py
repanier/models/offeritem.py
+25
-30
repanier/models/product.py
repanier/models/product.py
+35
-20
repanier/models/purchase.py
repanier/models/purchase.py
+1
-1
repanier/task/task_order.py
repanier/task/task_order.py
+15
-9
repanier/tools.py
repanier/tools.py
+36
-21
repanier/xlsx/xlsx_invoice.py
repanier/xlsx/xlsx_invoice.py
+41
-10
repanier/xlsx/xlsx_purchase.py
repanier/xlsx/xlsx_purchase.py
+0
-2
No files found.
repanier/admin/admin_filter.py
View file @
0157185d
...
...
@@ -119,7 +119,7 @@ class ProductFilterByVatLevel(SimpleListFilter):
def
lookups
(
self
,
request
,
model_admin
):
return
[(
p
[
0
],
p
[
1
])
for
p
in
settings
.
LUT_VAT
LUT_ALL_VAT
#
settings.LUT_VAT
]
def
queryset
(
self
,
request
,
queryset
):
...
...
repanier/admin/product.py
View file @
0157185d
...
...
@@ -51,7 +51,7 @@ class ProductResource(resources.ModelResource):
producer_unit_price
=
fields
.
Field
(
attribute
=
'producer_unit_price'
,
widget
=
TwoMoneysWidget
())
customer_unit_price
=
fields
.
Field
(
attribute
=
'customer_unit_price'
,
widget
=
TwoMoneysWidget
())
unit_deposit
=
fields
.
Field
(
attribute
=
'unit_deposit'
,
widget
=
TwoMoneysWidget
())
vat_level
=
fields
.
Field
(
attribute
=
'vat_level'
,
widget
=
ChoiceWidget
(
settings
.
LUT_VAT
,
settings
.
LUT
_VAT_REVERSE
))
vat_level
=
fields
.
Field
(
attribute
=
'vat_level'
,
widget
=
ChoiceWidget
(
LUT_ALL_VAT
,
LUT_ALL
_VAT_REVERSE
))
customer_minimum_order_quantity
=
fields
.
Field
(
attribute
=
'customer_minimum_order_quantity'
,
widget
=
ThreeDecimalsWidget
())
customer_increment_order_quantity
=
fields
.
Field
(
attribute
=
'customer_increment_order_quantity'
,
...
...
@@ -507,10 +507,13 @@ class ProductAdmin(ImportExportMixin, TranslatableAdmin):
production_mode_field
=
form
.
base_fields
[
"production_mode"
]
picture_field
=
form
.
base_fields
[
"picture2"
]
order_unit_field
=
form
.
base_fields
[
"order_unit"
]
vat_level_field
=
form
.
base_fields
[
"vat_level"
]
producer_field
.
widget
.
can_add_related
=
False
producer_field
.
widget
.
can_delete_related
=
False
producer_field
.
widget
.
attrs
[
'readonly'
]
=
True
department_for_customer_field
.
widget
.
can_delete_related
=
False
# TODO : Make it dependent of the producer country
vat_level_field
.
widget
.
choices
=
settings
.
LUT_VAT
order_unit_choices
=
LUT_PRODUCT_ORDER_UNIT_WO_SUBSCRIPTION
if
producer
is
not
None
:
...
...
repanier/admin/purchase.py
View file @
0157185d
...
...
@@ -60,7 +60,7 @@ class PurchaseResource(resources.ModelResource):
producer_row_price
=
fields
.
Field
(
attribute
=
'purchase_price'
,
widget
=
TwoMoneysWidget
(),
readonly
=
True
)
customer_row_price
=
fields
.
Field
(
attribute
=
'selling_price'
,
widget
=
TwoMoneysWidget
(),
readonly
=
True
)
vat_level
=
fields
.
Field
(
attribute
=
'offer_item__vat_level'
,
widget
=
ChoiceWidget
(
settings
.
LUT_VAT
,
settings
.
LUT
_VAT_REVERSE
),
readonly
=
True
)
widget
=
ChoiceWidget
(
LUT_ALL_VAT
,
LUT_ALL
_VAT_REVERSE
),
readonly
=
True
)
class
Meta
:
model
=
Purchase
...
...
repanier/const.py
View file @
0157185d
...
...
@@ -186,8 +186,6 @@ DICT_VAT_RATE = 1
DICT_VAT
=
{
VAT_100
:
(
_
(
'none'
),
DECIMAL_ZERO
),
VAT_200
:
(
_
(
'compensation 2%'
),
DECIMAL_0_02
),
VAT_300
:
(
_
(
'compensation 6%'
),
DECIMAL_0_06
),
VAT_315
:
(
_
(
'vat 2.1%'
),
DECIMAL_0_021
),
VAT_325
:
(
_
(
'vat 2.5%'
),
DECIMAL_0_025
),
VAT_350
:
(
_
(
'vat 3.8%'
),
DECIMAL_0_038
),
...
...
@@ -201,6 +199,36 @@ DICT_VAT = {
VAT_600
:
(
_
(
'vat 21%'
),
DECIMAL_0_21
),
}
LUT_ALL_VAT
=
(
(
VAT_100
,
_
(
'none'
)),
(
VAT_315
,
_
(
'vat 2.1%'
)),
(
VAT_325
,
_
(
'vat 2.5%'
)),
(
VAT_350
,
_
(
'vat 3.8%'
)),
(
VAT_360
,
_
(
'vat 4%'
)),
(
VAT_375
,
_
(
'vat 5.5%'
)),
(
VAT_400
,
_
(
'vat 6%'
)),
(
VAT_430
,
_
(
'vat 8%'
)),
(
VAT_460
,
_
(
'vat 10%'
)),
(
VAT_500
,
_
(
'vat 12%'
)),
(
VAT_590
,
_
(
'vat 20%'
)),
(
VAT_600
,
_
(
'vat 21%'
)),
)
LUT_ALL_VAT_REVERSE
=
(
(
_
(
'none'
),
VAT_100
),
(
_
(
'vat 2.1%'
),
VAT_315
),
(
_
(
'vat 2.5%'
),
VAT_325
),
(
_
(
'vat 3.8%'
),
VAT_350
),
(
_
(
'vat 4%'
),
VAT_360
),
(
_
(
'vat 5.5%'
),
VAT_375
),
(
_
(
'vat 6%'
),
VAT_400
),
(
_
(
'vat 8%'
),
VAT_430
),
(
_
(
'vat 10%'
),
VAT_460
),
(
_
(
'vat 12%'
),
VAT_500
),
(
_
(
'vat 20%'
),
VAT_590
),
(
_
(
'vat 21%'
),
VAT_600
),
)
BANK_NOT_LATEST_TOTAL
=
'100'
BANK_SUBSCRIPTION
=
'150'
BANK_COMPENSATION
=
'200'
# BANK_COMPENSATION may occurs in previous release of Repanier
...
...
repanier/models/offeritem.py
View file @
0157185d
...
...
@@ -48,7 +48,7 @@ class OfferItem(TranslatableModel):
)
# Important : Check select_related
product
=
models
.
ForeignKey
(
'Product'
,
verbose_name
=
_
(
"product"
),
null
=
True
,
blank
=
True
,
default
=
None
,
on_delete
=
models
.
PROTECT
)
'Product'
,
verbose_name
=
_
(
"product"
),
on_delete
=
models
.
PROTECT
)
picture2
=
AjaxPictureField
(
verbose_name
=
_
(
"picture"
),
null
=
True
,
blank
=
True
,
...
...
@@ -102,7 +102,7 @@ class OfferItem(TranslatableModel):
default
=
DECIMAL_ZERO
,
max_digits
=
8
,
decimal_places
=
2
)
vat_level
=
models
.
CharField
(
max_length
=
3
,
choices
=
settings
.
LUT_VAT
,
choices
=
LUT_ALL_VAT
,
#
settings.LUT_VAT,
default
=
settings
.
DICT_VAT_DEFAULT
,
verbose_name
=
_
(
"tax"
))
...
...
@@ -322,7 +322,7 @@ class OfferItem(TranslatableModel):
return
'<span class="glyphicon glyphicon-heart%s" onclick="like_ajax(%d);return false;"></span>'
%
(
EMPTY_STRING
if
self
.
product
.
likes
.
filter
(
id
=
user
.
id
).
only
(
"id"
).
exists
()
else
"-empty"
,
self
.
id
)
def
get_
order_name
(
self
,
is_quantity_invoiced
=
False
,
box_unicode
=
BOX_UNICODE
):
def
get_
qty_display
(
self
,
is_quantity_invoiced
=
False
,
box_unicode
=
BOX_UNICODE
):
if
self
.
is_box
:
# To avoid unicode error in email_offer.send_open_order
qty_display
=
box_unicode
...
...
@@ -343,7 +343,27 @@ class OfferItem(TranslatableModel):
for_customer
=
False
,
without_price_display
=
True
)
return
'%s %s'
%
(
self
.
long_name
,
qty_display
)
return
qty_display
def
get_qty_and_price_display
(
self
,
is_quantity_invoiced
=
False
,
customer_price
=
True
,
box_unicode
=
BOX_UNICODE
):
qty_display
=
self
.
get_qty_display
(
is_quantity_invoiced
,
box_unicode
)
unit_price
=
self
.
get_unit_price
(
customer_price
=
customer_price
)
if
len
(
qty_display
)
>
0
:
if
self
.
unit_deposit
.
amount
>
DECIMAL_ZERO
:
return
'%s, %s + ♻ %s'
%
(
qty_display
,
unit_price
,
self
.
unit_deposit
)
else
:
return
'%s, %s'
%
(
qty_display
,
unit_price
)
else
:
if
self
.
unit_deposit
.
amount
>
DECIMAL_ZERO
:
return
'%s + ♻ %s'
%
(
unit_price
,
self
.
unit_deposit
)
else
:
return
'%s'
%
unit_price
def
get_order_name
(
self
,
is_quantity_invoiced
=
False
,
box_unicode
=
BOX_UNICODE
):
return
'%s %s'
%
(
self
.
long_name
,
self
.
get_qty_display
(
is_quantity_invoiced
,
box_unicode
))
def
get_long_name_with_producer_price
(
self
):
return
self
.
get_long_name
(
customer_price
=
False
)
...
...
@@ -352,31 +372,7 @@ class OfferItem(TranslatableModel):
get_long_name_with_producer_price
.
admin_order_field
=
'translations__long_name'
def
get_long_name
(
self
,
is_quantity_invoiced
=
False
,
customer_price
=
True
,
box_unicode
=
BOX_UNICODE
):
if
self
.
is_box
:
# To avoid unicode error in email_offer.send_open_order
qty_display
=
box_unicode
else
:
if
is_quantity_invoiced
and
self
.
order_unit
==
PRODUCT_ORDER_UNIT_PC_KG
:
qty_display
=
get_display
(
qty
=
1
,
order_average_weight
=
self
.
order_average_weight
,
order_unit
=
PRODUCT_ORDER_UNIT_KG
,
for_customer
=
False
,
without_price_display
=
True
)
else
:
qty_display
=
get_display
(
qty
=
1
,
order_average_weight
=
self
.
order_average_weight
,
order_unit
=
self
.
order_unit
,
for_customer
=
False
,
without_price_display
=
True
)
unit_price
=
self
.
get_unit_price
(
customer_price
=
customer_price
)
if
self
.
unit_deposit
.
amount
>
DECIMAL_ZERO
:
return
'%s %s, %s + ♻ %s'
%
(
self
.
long_name
,
qty_display
,
unit_price
,
self
.
unit_deposit
)
else
:
return
'%s %s, %s'
%
(
self
.
long_name
,
qty_display
,
unit_price
)
return
'%s %s'
%
(
self
.
long_name
,
self
.
get_qty_and_price_display
(
is_quantity_invoiced
,
customer_price
,
box_unicode
))
get_long_name
.
short_description
=
(
_
(
"long_name"
))
get_long_name
.
allow_tags
=
False
...
...
@@ -390,7 +386,6 @@ class OfferItem(TranslatableModel):
verbose_name_plural
=
_
(
"offer's items"
)
unique_together
=
(
"permanence"
,
"product"
,)
index_together
=
[
# ["permanence", "product"],
[
"id"
,
"order_unit"
]
]
...
...
repanier/models/product.py
View file @
0157185d
...
...
@@ -80,7 +80,7 @@ class Product(TranslatableModel):
vat_level
=
models
.
CharField
(
max_length
=
3
,
choices
=
settings
.
LUT_VAT
,
choices
=
LUT_ALL_VAT
,
#
settings.LUT_VAT,
default
=
settings
.
DICT_VAT_DEFAULT
,
verbose_name
=
_
(
"tax"
))
stock
=
models
.
DecimalField
(
...
...
@@ -132,8 +132,8 @@ class Product(TranslatableModel):
is_active
=
models
.
BooleanField
(
_
(
"is_active"
),
default
=
True
)
is_updated_on
=
models
.
DateTimeField
(
_
(
"is_updated_on"
),
auto_now
=
True
,
blank
=
True
)
external_id_producer
=
models
.
BigIntegerField
(
null
=
True
,
blank
=
True
,
default
=
None
)
external_id_product
=
models
.
BigIntegerField
(
null
=
True
,
blank
=
True
,
default
=
None
)
#
external_id_producer = models.BigIntegerField(null=True, blank=True, default=None)
#
external_id_product = models.BigIntegerField(null=True, blank=True, default=None)
@
property
def
total_likes
(
self
):
...
...
@@ -233,11 +233,19 @@ class Product(TranslatableModel):
offer_price
=
self
.
get_unit_price
()
return
offer_price
def
get_long_name
(
self
,
box_unicode
=
BOX_UNICODE
,
customer_price
=
True
):
if
self
.
id
:
if
self
.
is_box
:
# To avoid unicode error when print
qty_display
=
box_unicode
def
get_qty_display
(
self
,
is_quantity_invoiced
=
False
,
box_unicode
=
BOX_UNICODE
):
if
self
.
is_box
:
# To avoid unicode error in email_offer.send_open_order
qty_display
=
box_unicode
else
:
if
is_quantity_invoiced
and
self
.
order_unit
==
PRODUCT_ORDER_UNIT_PC_KG
:
qty_display
=
get_display
(
qty
=
1
,
order_average_weight
=
self
.
order_average_weight
,
order_unit
=
PRODUCT_ORDER_UNIT_KG
,
for_customer
=
False
,
without_price_display
=
True
)
else
:
qty_display
=
get_display
(
qty
=
1
,
...
...
@@ -246,20 +254,27 @@ class Product(TranslatableModel):
for_customer
=
False
,
without_price_display
=
True
)
unit_price
=
self
.
get_unit_price
(
customer_price
=
customer_price
)
unit_deposit
=
self
.
unit_deposit
if
len
(
qty_display
)
>
0
:
if
unit_deposit
.
amount
>
DECIMAL_ZERO
:
return
'%s %s, %s ♻ %s'
%
(
self
.
long_name
,
qty_display
,
unit_price
,
unit_deposit
)
else
:
return
'%s %s, %s'
%
(
self
.
long_name
,
qty_display
,
unit_price
)
return
qty_display
def
get_qty_and_price_display
(
self
,
is_quantity_invoiced
=
False
,
customer_price
=
True
,
box_unicode
=
BOX_UNICODE
):
qty_display
=
self
.
get_qty_display
(
is_quantity_invoiced
,
box_unicode
)
unit_price
=
self
.
get_unit_price
(
customer_price
=
customer_price
)
if
len
(
qty_display
)
>
0
:
if
self
.
unit_deposit
.
amount
>
DECIMAL_ZERO
:
return
'%s, %s + ♻ %s'
%
(
qty_display
,
unit_price
,
self
.
unit_deposit
)
else
:
if
unit_deposit
.
amount
>
DECIMAL_ZERO
:
return
'%s, %s ♻ %s'
%
(
self
.
long_name
,
unit_price
,
unit_deposit
)
else
:
return
'%s, %s'
%
(
self
.
long_name
,
unit_price
)
return
'%s, %s'
%
(
qty_display
,
unit_price
)
else
:
raise
AttributeError
if
self
.
unit_deposit
.
amount
>
DECIMAL_ZERO
:
return
'%s + ♻ %s'
%
(
unit_price
,
self
.
unit_deposit
)
else
:
return
'%s'
%
unit_price
def
get_long_name
(
self
,
is_quantity_invoiced
=
False
,
customer_price
=
True
,
box_unicode
=
BOX_UNICODE
):
return
'%s %s'
%
(
self
.
long_name
,
self
.
get_qty_and_price_display
(
is_quantity_invoiced
,
customer_price
,
box_unicode
))
get_long_name
.
short_description
=
(
_
(
"long_name"
))
get_long_name
.
allow_tags
=
True
...
...
repanier/models/purchase.py
View file @
0157185d
...
...
@@ -96,7 +96,7 @@ class Purchase(models.Model):
vat_level
=
models
.
CharField
(
max_length
=
3
,
choices
=
settings
.
LUT_VAT
,
choices
=
LUT_ALL_VAT
,
#
settings.LUT_VAT,
default
=
settings
.
DICT_VAT_DEFAULT
,
verbose_name
=
_
(
"tax"
))
...
...
repanier/task/task_order.py
View file @
0157185d
...
...
@@ -379,14 +379,16 @@ def close_order_delivery(permanence, delivery, all_producers, producers_id=None)
for
offer_item
in
OfferItem
.
objects
.
filter
(
permanence_id
=
permanence
.
id
,
# is_active=False,
order_unit
=
PRODUCT_ORDER_UNIT_DEPOSIT
).
order_by
(
'?'
):
permanence
.
producers
.
add
(
offer_item
.
producer_id
)
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
1
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
0
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
.
id
,
offer_item
,
q_order
=
1
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
.
id
,
offer_item
,
q_order
=
0
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
# 4 - Add Membership fee Subscription
if
repanier
.
apps
.
REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION
>
0
:
# There is a membership fee
if
customer
.
membership_fee_valid_until
<
today
:
permanence
.
producers
.
add
(
membership_fee_offer_item
.
producer_id
)
create_or_update_one_purchase
(
customer
,
membership_fee_offer_item
,
q_order
=
1
,
batch_job
=
True
,
create_or_update_one_purchase
(
customer
.
id
,
membership_fee_offer_item
,
q_order
=
1
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
customer
.
membership_fee_valid_until
=
add_months
(
customer
.
membership_fee_valid_until
,
...
...
@@ -400,7 +402,9 @@ def close_order_delivery(permanence, delivery, all_producers, producers_id=None)
for
customer
in
Customer
.
objects
.
filter
(
is_active
=
True
,
may_order
=
True
,
represent_this_buyinggroup
=
False
).
order_by
(
'?'
):
permanence
.
producers
.
add
(
offer_item
.
producer_id
)
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
1
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
.
id
,
offer_item
,
q_order
=
1
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
delivery
.
set_status
(
PERMANENCE_CLOSED
,
all_producers
,
producers_id
)
...
...
@@ -471,7 +475,9 @@ def close_order(permanence, all_producers, producers_id=None):
offer_item_qs
=
offer_item_qs
.
filter
(
producer_id__in
=
producers_id
)
for
offer_item
in
offer_item_qs
:
buying_group
=
Customer
.
objects
.
filter
(
is_active
=
True
,
represent_this_buyinggroup
=
True
).
order_by
(
'?'
).
first
()
create_or_update_one_purchase
(
buying_group
,
offer_item
,
q_order
=
1
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
buying_group
.
id
,
offer_item
,
q_order
=
1
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
membership_fee_product
=
Product
.
objects
.
filter
(
is_membership_fee
=
True
,
is_active
=
True
).
order_by
(
'?'
).
first
()
membership_fee_product
.
producer_unit_price
=
repanier
.
apps
.
REPANIER_SETTINGS_MEMBERSHIP_FEE
# Update the prices
...
...
@@ -495,14 +501,14 @@ def close_order(permanence, all_producers, producers_id=None):
if
not
all_producers
:
offer_item_qs
=
offer_item_qs
.
filter
(
producer_id__in
=
producers_id
)
for
offer_item
in
offer_item_qs
:
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
1
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
0
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
.
id
,
offer_item
,
q_order
=
1
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
.
id
,
offer_item
,
q_order
=
0
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
# 4 - Add Add Membership fee Subscription
if
repanier
.
apps
.
REPANIER_SETTINGS_MEMBERSHIP_FEE_DURATION
>
0
:
# There is a membership fee
if
customer
.
membership_fee_valid_until
<
today
:
permanence
.
producers
.
add
(
membership_fee_offer_item
.
producer_id
)
create_or_update_one_purchase
(
customer
,
membership_fee_offer_item
,
q_order
=
1
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
.
id
,
membership_fee_offer_item
,
q_order
=
1
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
while
customer
.
membership_fee_valid_until
<
today
:
# Do not pay the membership fee if no order passed during a certain amount of time
customer
.
membership_fee_valid_until
=
add_months
(
...
...
@@ -522,7 +528,7 @@ def close_order(permanence, all_producers, producers_id=None):
represent_this_buyinggroup
=
False
).
order_by
(
'?'
):
permanence
.
producers
.
add
(
offer_item
.
producer_id
)
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
1
,
batch_job
=
True
,
is_box_content
=
False
)
create_or_update_one_purchase
(
customer
.
id
,
offer_item
,
q_order
=
1
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
# Disable subscription for next permanence
Product
.
objects
.
filter
(
order_unit
=
PRODUCT_ORDER_UNIT_SUBSCRIPTION
,
is_into_offer
=
True
,
is_membership_fee
=
False
...
...
repanier/tools.py
View file @
0157185d
...
...
@@ -346,6 +346,17 @@ def get_invoice_unit(order_unit=PRODUCT_ORDER_UNIT_PC, qty=0):
return
unit
def
get_reverse_invoice_unit
(
unit
):
# reverse of tools get_invoice_unit
if
unit
==
_
(
"/ kg"
):
order_unit
=
PRODUCT_ORDER_UNIT_KG
elif
unit
==
_
(
"/ l"
):
order_unit
=
PRODUCT_ORDER_UNIT_LT
else
:
order_unit
=
PRODUCT_ORDER_UNIT_PC
return
order_unit
def
get_preparator_unit
(
order_unit
=
PRODUCT_ORDER_UNIT_PC
):
# Used when producing the preparation list.
if
order_unit
in
[
PRODUCT_ORDER_UNIT_PC
,
PRODUCT_ORDER_UNIT_PC_PRICE_KG
,
PRODUCT_ORDER_UNIT_PC_PRICE_LT
,
...
...
@@ -956,7 +967,7 @@ def update_or_create_purchase(customer=None, offer_item_id=None, q_order=None, v
if
quantity_ordered
<
DECIMAL_ZERO
:
quantity_ordered
=
DECIMAL_ZERO
purchase
,
updated
=
create_or_update_one_purchase
(
customer
,
box_offer_item
,
q_order
=
quantity_ordered
,
batch_job
=
batch_job
,
is_box_content
=
True
customer
.
id
,
box_offer_item
,
q_order
=
quantity_ordered
,
batch_job
=
batch_job
,
is_box_content
=
True
)
else
:
updated
=
False
...
...
@@ -993,7 +1004,7 @@ def update_or_create_purchase(customer=None, offer_item_id=None, q_order=None, v
transaction
.
savepoint_rollback
(
sid
)
if
not
offer_item
.
is_box
or
updated
:
purchase
,
updated
=
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
q_order
,
batch_job
=
batch_job
,
customer
.
id
,
offer_item
,
q_order
=
q_order
,
batch_job
=
batch_job
,
is_box_content
=
False
)
if
not
batch_job
and
apps
.
REPANIER_SETTINGS_DISPLAY_PRODUCER_ON_ORDER_FORM
:
...
...
@@ -1292,42 +1303,45 @@ def my_order_confirmation_email_send_to(customer):
return
msg_confirmation
def
create_or_update_one_purchase
(
customer
,
offer_item
,
q_order
=
None
,
batch_job
=
False
,
is_box_content
=
False
):
def
create_or_update_one_purchase
(
customer
_id
,
offer_item
,
permanence_date
=
None
,
status
=
PERMANENCE_OPENED
,
q_order
=
None
,
batch_job
=
False
,
is_box_content
=
False
):
# The batch_job flag is used because we need to forbid
# customers to add purchases during the close_orders_async or other batch_job process
# when the status is PERMANENCE_WAIT_FOR_SEND
purchase
=
models
.
Purchase
.
objects
.
filter
(
customer_id
=
customer
.
id
,
customer_id
=
customer
_
id
,
offer_item_id
=
offer_item
.
id
,
is_box_content
=
is_box_content
).
order_by
(
'?'
).
first
()
if
batch_job
:
if
purchase
is
None
:
permanence
=
models
.
Permanence
.
objects
.
filter
(
id
=
offer_item
.
permanence_id
)
\
.
only
(
"permanence_date"
)
\
.
order_by
(
'?'
).
first
()
permanence_date
=
permanence_date
or
models
.
Permanence
.
objects
.
filter
(
id
=
offer_item
.
permanence_id
).
only
(
"permanence_date"
).
order_by
(
'?'
).
first
().
permanence_date
purchase
=
models
.
Purchase
.
objects
.
create
(
permanence_id
=
offer_item
.
permanence_id
,
permanence_date
=
permanence
.
permanence
_date
,
permanence_date
=
permanence_date
,
offer_item_id
=
offer_item
.
id
,
producer_id
=
offer_item
.
producer_id
,
customer_id
=
customer
.
id
,
quantity_ordered
=
q_order
,
quantity_invoiced
=
DECIMAL_ZERO
,
customer_id
=
customer
_
id
,
quantity_ordered
=
q_order
if
status
<
PERMANENCE_SEND
else
DECIMAL_ZERO
,
quantity_invoiced
=
q_order
if
status
>=
PERMANENCE_SEND
else
DECIMAL_ZERO
,
is_box_content
=
is_box_content
,
status
=
PERMANENCE_OPENED
status
=
status
)
if
q_order
==
DECIMAL_ZERO
:
purchase
.
comment
=
_
(
"Cancelled qty : %s"
)
%
number_format
(
purchase
.
quantity_ordered
,
4
)
purchase
.
quantity_ordered
=
q_order
purchase
.
save
()
else
:
if
status
<
PERMANENCE_SEND
:
if
q_order
==
DECIMAL_ZERO
:
purchase
.
comment
=
_
(
"Cancelled qty : %s"
)
%
number_format
(
purchase
.
quantity_ordered
,
4
)
purchase
.
quantity_ordered
=
q_order
else
:
purchase
.
quantity_invoiced
=
q_order
purchase
.
save
()
return
purchase
,
True
else
:
permanence_is_opened
=
models
.
CustomerInvoice
.
objects
.
filter
(
permanence_id
=
offer_item
.
permanence_id
,
customer_id
=
customer
.
id
,
status
=
PERMANENCE_OPENED
customer_id
=
customer
_
id
,
status
=
status
).
order_by
(
'?'
).
exists
()
if
permanence_is_opened
:
if
offer_item
.
limit_order_quantity_to_stock
:
...
...
@@ -1339,7 +1353,7 @@ def create_or_update_one_purchase(customer, offer_item, q_order=None, batch_job=
if
is_box_content
and
q_alert
<
q_order
:
# Select one purchase
non_box_purchase
=
models
.
Purchase
.
objects
.
filter
(
customer_id
=
customer
.
id
,
customer_id
=
customer
_
id
,
offer_item_id
=
offer_item
.
id
,
is_box_content
=
False
).
order_by
(
'?'
).
first
()
...
...
@@ -1373,11 +1387,11 @@ def create_or_update_one_purchase(customer, offer_item, q_order=None, batch_job=
permanence_date
=
permanence
.
permanence_date
,
offer_item_id
=
offer_item
.
id
,
producer_id
=
offer_item
.
producer_id
,
customer_id
=
customer
.
id
,
customer_id
=
customer
_
id
,
quantity_ordered
=
q_order
,
quantity_invoiced
=
DECIMAL_ZERO
,
is_box_content
=
is_box_content
,
status
=
PERMANENCE_OPENED
status
=
status
)
return
purchase
,
True
else
:
...
...
@@ -1574,6 +1588,7 @@ def update_offer_item(product_id=None, producer_id=None):
cache
.
clear
()
@
transaction
.
atomic
()
def
get_or_create_offer_item
(
permanence
,
product_id
,
producer_id
=
None
):
offer_item_qs
=
models
.
OfferItem
.
objects
.
filter
(
permanence_id
=
permanence
.
id
,
...
...
repanier/xlsx/xlsx_invoice.py
View file @
0157185d
# -*- coding: utf-8
from
__future__
import
unicode_literals
from
django.conf
import
settings
from
django.db
import
transaction
from
django.http
import
HttpResponse
from
django.utils
import
translation
,
timezone
from
django.utils.text
import
slugify
from
django.utils.translation
import
ugettext_lazy
as
_
from
openpyxl
import
load_workbook
from
openpyxl.style
import
Border
...
...
@@ -14,14 +13,14 @@ import repanier.apps
from
export_tools
import
*
from
repanier.models
import
Configuration
from
repanier.const
import
*
from
repanier.models
import
BankAccount
,
Permanence
,
Purchase
from
repanier.models
import
BankAccount
,
Permanence
,
P
roduct
,
P
urchase
from
repanier.models
import
Customer
from
repanier.models
import
CustomerInvoice
from
repanier.models
import
Producer
from
repanier.models
import
ProducerInvoice
from
repanier.tools
import
get_invoice_unit
from
repanier.xlsx.xlsx_stock
import
export_permanence_stock
from
repanier.xlsx.import_tools
import
get_customer_
2_id_dict
,
get_producer_2_id_dict
,
get_customer_
email_2_id_dict
,
\
from
repanier.tools
import
get_invoice_unit
,
get_reverse_invoice_unit
,
get_or_create_offer_item
,
\
create_or_update_one_purchase
from
repanier.xlsx.import_tools
import
get_customer_email_2_id_dict
,
\
get_header
,
get_row
...
...
@@ -259,13 +258,14 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
]
else
:
row
+=
[
(
_
(
"Vat"
),
10
,
purchase
.
get_vat_level_display
(),
NumberFormat
.
FORMAT_TEXT
,
False
)
(
_
(
"Vat
level
"
),
10
,
purchase
.
get_vat_level_display
(),
NumberFormat
.
FORMAT_TEXT
,
False
)
]
row
+=
[
(
_
(
"comment"
),
30
,
EMPTY_STRING
if
purchase
.
comment
is
None
else
purchase
.
comment
,
NumberFormat
.
FORMAT_TEXT
,
False
),
(
_
(
"invoice_status"
),
10
,
purchase
.
get_status_display
(),
NumberFormat
.
FORMAT_TEXT
,
False
),
(
_
(
"CustId_02"
),
10
,
purchase
.
customer
.
user
.
email
,
NumberFormat
.
FORMAT_TEXT
,
False
),
(
_
(
"customer"
),
10
,
purchase
.
customer
.
user
.
email
,
NumberFormat
.
FORMAT_TEXT
,
False
),
(
_
(
"reference"
),
10
,
purchase
.
offer_item
.
reference
,
NumberFormat
.
FORMAT_TEXT
,
False
),
]
if
row_num
==
0
:
...
...
@@ -302,6 +302,7 @@ def export_invoice(permanence=None, year=None, customer=None, producer=None, wb=
if
hide_producer_prices
and
hide_customer_prices
:
ws
.
column_dimensions
[
get_column_letter
(
15
)].
visible
=
False
ws
.
column_dimensions
[
get_column_letter
(
18
)].
visible
=
False
ws
.
column_dimensions
[
get_column_letter
(
19
)].
visible
=
False
for
col_num
in
range
(
len
(
row
)):
c
=
ws
.
cell
(
row
=
row_num
,
column
=
col_num
)
c
.
style
.
borders
.
top
.
border_style
=
Border
.
BORDER_THIN
...
...
@@ -354,6 +355,7 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
header
=
get_header
(
worksheet
)
if
header
:
now
=
timezone
.
now
().
date
()
lut_reverse_vat
=
dict
(
LUT_ALL_VAT_REVERSE
)
import_counter
=
0
row_num
=
1
sid
=
transaction
.
savepoint
()
...
...
@@ -361,12 +363,14 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
permanence
=
Permanence
.
objects
.
create
(
permanence_date
=
now
,
short_name
=
invoice_reference
short_name
=
invoice_reference
,
status
=
PERMANENCE_SEND
,
highest_status
=
PERMANENCE_SEND
)
permanence
.
producers
.
add
(
producer
)
row
=
get_row
(
worksheet
,
header
,
row_num
)
while
row
and
not
error
:
customer_name
=
row
[
_
(
"
CustId_02
"
)]
customer_name
=
row
[
_
(
"
customer
"
)]
if
customer_name
:
if
customer_name
in
customer_2_id_dict
:
customer_id
=
customer_2_id_dict
[
customer_name
]
...
...
@@ -374,7 +378,32 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
error
=
True
error_msg
=
_
(
"Row %(row_num)d : No valid customer"
)
%
{
'row_num'
:
row_num
+
1
}
break
product_reference
=
row
[
_
(
"reference"
)]
unit
=
row
[
_
(
"Unit"
)]
order_unit
=
get_reverse_invoice_unit
(
unit
)
vat
=
row
[
_
(
"Vat level"
)]
vat_level
=
lut_reverse_vat
[
vat
]
product
=
Product
.
objects
.
filter
(
producer_id
=
producer
.
id
,
reference
=
product_reference
).
order_by
(
'?'
).
first
()
if
product
is
None
:
product
=
Product
.
objects
.
create
(
producer
=
producer
,
reference
=
product_reference
,
)
product
.
long_name
=
row
[
_
(
"Product"
)]
product
.
order_unit
=
order_unit
product
.
vat_level
=
vat_level
product
.
save
()
qty_and_price_display
=
product
.
get_qty_and_price_display
()
if
product
.
long_name
.
endswith
(
qty_and_price_display
):
product
.
long_name
=
product
.
long_name
[:
-
len
(
qty_and_price_display
)]
product
.
save
()
offer_item
=
get_or_create_offer_item
(
permanence
,
product
.
id
,
producer
.
id
)
create_or_update_one_purchase
(
customer_id
,
offer_item
,
q_order
=
1
,
status
=
PERMANENCE_SEND
,
permanence_date
=
permanence
.
permanence_date
,
batch_job
=
True
,
is_box_content
=
False
)
import_counter
+=
1
row_num
+=
1
row
=
get_row
(
worksheet
,
header
,
row_num
)
...
...
@@ -391,6 +420,8 @@ def import_invoice_sheet(worksheet, invoice_reference=None,
error_msg
=
"%s"
%
_
(
"Nothing to import."
)
if
error
:
transaction
.
savepoint_rollback
(
sid
)
else
:
transaction
.
savepoint_commit
(
sid
)
return
error
,
error_msg
...
...
repanier/xlsx/xlsx_purchase.py
View file @
0157185d
...
...
@@ -2,9 +2,7 @@
from
__future__
import
unicode_literals
from
django.db
import
transaction
from
django.http
import
HttpResponse
from
django.utils
import
translation
from
django.utils.text
import
slugify
from
django.utils.translation
import
ugettext_lazy
as
_
from
openpyxl
import
load_workbook
from
openpyxl.style
import
Fill
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment