>+ def save(self, *args, **kwargs): 164
+        self.sub_total = self.price * self.n_unit
165
+        self.vat  = self.sub_total * decimal.Decimal(VAT)
166
+        self.total = self.sub_total + self.vat
167
+        super(Sale, self).save(*args, **kwargs)
168
+
93 169
 class Product(GenericModel, models.Model ):
94 170
     name = models.CharField(max_length=200)
95 171
     code = models.CharField(max_length=200)
96 172
     product_type = TreeForeignKey('ProductType', on_delete=models.SET_NULL, null=True)
97 173
     description = models.TextField(blank=True, null=True)
98 174
     store = models.ForeignKey('Store', on_delete=models.CASCADE, null=True, blank=False)
99
-    price = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=7)
175
+    price = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=10)
176
+
177
+
178
+    details  = models.JSONField(null=True, blank=True)
179
+
180
+    n_unit = models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)
181
+    unit_name = models.CharField(max_length=200, null=True)
182
+
183
+    def __str__(self):
184
+        return f"{self.name} {self.code}"
185
+
186
+class Vendor(GenericModel, models.Model ):
187
+    name = models.CharField(max_length=200)
188
+    code = models.CharField(max_length=200)
189
+    #product_type = TreeForeignKey('ProductType', on_delete=models.SET_NULL, null=True)
190
+    product = models.ForeignKey('Product', on_delete=models.CASCADE)
191
+    description = models.TextField(blank=True, null=True)
192
+    store = models.ForeignKey('Store', on_delete=models.CASCADE, null=True, blank=False)
193
+    price = models.DecimalField(null=True, blank=True, decimal_places=2, max_digits=10)
194
+
100 195
 
101 196
     details  = models.JSONField(null=True, blank=True)
102 197
 
103 198
     n_unit = models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)
104 199
     unit_name = models.CharField(max_length=200, null=True)
105 200
 
201
+    tel = models.CharField(max_length=100, null=True, blank=True)
202
+    line_id = models.CharField(max_length=100, null=True, blank=True)
203
+    email = models.EmailField(null=True, blank=True)
204
+
205
+    address_text = models.TextField(blank=False, null=False)
206
+    address = map_fields.AddressField(max_length=200)
207
+    geolocation = map_fields.GeoLocationField(max_length=100)
208
+
209
+
106 210
     def __str__(self):
107 211
         return f"{self.name} {self.code}"
108 212
 
213
+
109 214
 class ProductSKU(GenericModel, models.Model ):
110 215
     sku = models.CharField(max_length=200)
111 216
     product  = models.ForeignKey('Product', on_delete=models.CASCADE, null=True)
@@ -117,8 +222,12 @@ class ProductSKU(GenericModel, models.Model ):
117 222
     n_unit = models.DecimalField(blank=True, decimal_places=2, max_digits=7, null=True)
118 223
     unit_name = models.CharField(max_length=200, null=True)
119 224
 
225
+    def __str__(self):
226
+        return f"{self.sku} {self.product} @{self.price}(THB)"
227
+
120 228
 class Photo(GenericModel, models.Model):
121 229
     name = models.CharField(max_length=200,  blank=True)
230
+    order_n = models.IntegerField(default=0, blank=True)
122 231
     photo  = models.ImageField(upload_to="uploads/%Y/%m/%d/", blank=False, verbose_name="Photo")
123 232
     product = models.ForeignKey('Product', on_delete=models.CASCADE, null=True)
124 233
 

+ 17 - 0
app/fruit/templates/fruit/_paging.html

@@ -0,0 +1,17 @@
1
+<div class="pagination">
2
+    <span class="step-links">
3
+        {% if page_obj.has_previous %}
4
+            <a href="?page=1">&laquo; first</a>
5
+            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
6
+        {% endif %}
7
+
8
+        <span class="current">
9
+            Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
10
+        </span>
11
+
12
+        {% if page_obj.has_next %}
13
+            <a href="?page={{ page_obj.next_page_number }}">next</a>
14
+            <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
15
+        {% endif %}
16
+    </span>
17
+</div>

+ 13 - 0
app/fruit/templates/fruit/_searchcenter.html

@@ -0,0 +1,13 @@
1
+{% load crispy_forms_tags %}
2
+<form method="get">
3
+    <div class='row'>
4
+        <!--
5
+            {{ filter.form.fields }} -->
6
+    {% for f0  in filter.form %}
7
+        <div class='col-md-3'>
8
+            {{ f0 | as_crispy_field}}  
9
+        </div>
10
+    {% endfor %}
11
+    </div>
12
+    <input type="submit" class='btn btn-primary' value='Search'/>
13
+</form>

+ 25 - 0
app/fruit/templates/fruit/inbox_form.html

@@ -0,0 +1,25 @@
1
+{% extends "fruit/inbox_index.html" %}
2
+{% load static %}
3
+{% load crispy_forms_tags %}
4
+{% load django_bootstrap_breadcrumbs %}
5
+
6
+{% block header %}            
7
+{{ form.media  }}
8
+{% endblock %}
9
+
10
+{% block breadcrumbs %}
11
+    {{ block.super }}
12
+    {% breadcrumb "Inbox Form" "fruit:inbox_edit" form.instance.pk %}
13
+{% endblock %}
14
+
15
+{% block store_main %}
16
+<h2>Inbox Form</h2>
17
+<form  method="post" enctype="multipart/form-data">
18
+    {% csrf_token %}
19
+    {{ form | crispy  }}
20
+    <br>
21
+    <input type='submit' class='btn btn-primary' value="Update" />
22
+
23
+</form>
24
+
25
+{% endblock %}

+ 50 - 0
app/fruit/templates/fruit/inbox_index.html

@@ -0,0 +1,50 @@
1
+{% extends "fruit/mystore.html" %}
2
+{% load static %}
3
+{% load crispy_forms_tags %}
4
+
5
+{% block header %}            
6
+{% endblock %}
7
+
8
+{% load django_bootstrap_breadcrumbs %}
9
+{% block breadcrumbs %}
10
+    {{ block.super }}
11
+    {% breadcrumb "Inboxes" "fruit:inbox_index" %}
12
+{% endblock %}
13
+
14
+{% block store_main %}
15
+<!--
16
+<a  class='btn btn-primary' href="{% url "fruit:product_create" %}">Create Product</a> -->
17
+<hr>
18
+<h2>
19
+    Inbox Index</h2>
20
+{% include "fruit/_searchcenter.html" %}
21
+<hr>
22
+<table class='table table-borded table-striped'>
23
+    <thead>
24
+        <tr>
25
+            <th>ID</th>
26
+            <th>Store</th>
27
+            <th>Product</th>
28
+            <th>Buyer</th>
29
+            <th>Subject</th>
30
+            <th>Body</th>
31
+            <th>Status</th>
32
+            <th>Created At</th></tr>
33
+    </thead>
34
+    <tbody>
35
+{% for p in page_obj %}
36
+        <tr>
37
+            <td><a href="{% url "fruit:inbox_edit" pk=p.pk %}">{{ p.id }}</a></td><td>{{ p.product }}</td>
38
+            <td>{{ p.store}}</td>
39
+            <td>{{ p.product }}</td>
40
+            <td>{{ p.buyer }}</td>
41
+            <td>{{ p.subject }}</td>
42
+            <td>{{ p.body }}</td>
43
+            <td>{{ p.status }}</td>
44
+            <td>{{ p.created_at }}</td>
45
+        </tr>
46
+{% endfor %}
47
+    </tbody>
48
+</table>
49
+{% include "fruit/_paging.html" %}
50
+{% endblock %}

+ 12 - 3
app/fruit/templates/fruit/mystore.html

@@ -1,6 +1,7 @@
1 1
 {% extends "front/base.html" %}
2 2
 {% load static %}
3 3
 {% load crispy_forms_tags %}
4
+{% load django_bootstrap_breadcrumbs %}
4 5
 
5 6
 {% block header %}            
6 7
 {{ storeForm.media  }}
@@ -8,21 +9,29 @@
8 9
 
9 10
 {% block content %}
10 11
 <h1>My Store</h1>
12
+<!-- 
11 13
 <form method=post>
12 14
     {% csrf_token %}
13 15
     <input type='text' name='name' class='form-control' placeholder='Store Name'/>
14 16
     <input type='submit' class='btn btn-primary' name='createStore' value="Create Store" />
15 17
 </form>
16
-<hr>
18
+<hr> -->
17 19
 <div class="d-flex align-items-start">
18 20
   <div class="nav flex-column nav-pills me-3 col-md-3 col-lg-2" id="v-pills-tab" role="tablist" aria-orientation="vertical">
19 21
       <a class="nav-link {{ mystore|yesno:"active," }}" id="v-pills-home-tab"  href="{% url "fruit:mystore" %}" type="button" role="tab" aria-controls="v-pills-home" aria-selected="true">Info</a>
20 22
       <a class="nav-link {{ product|yesno:"active," }}" id="v-pills-profile-tab"  href="{% url "fruit:product_index" %}" type="button" role="tab" aria-controls="v-pills-profile" aria-selected="false">Products</a>
21
-    <a class="nav-link" id="v-pills-messages-tab" data-toggle="pill" data-bs-target="#v-pills-messages" type="button" role="tab" aria-controls="v-pills-messages" aria-selected="false">Inbox</a>
22
-    <a class="nav-link" id="v-pills-settings-tab" data-toggle="pill" data-bs-target="#v-pills-settings" type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false">Saled Items</a>
23
+    <a class="nav-link" id="v-pills-messages-tab" href="{% url "fruit:inbox_index" %}" type="button" role="tab" aria-controls="v-pills-messages" aria-selected="false">Inbox</a>
24
+    <a class="nav-link {{ sale_active|yesno:"active," }}" id="v-pills-settings-tab" href="{% url "fruit:sale_index" %}"  type="button" role="tab" aria-controls="v-pills-settings" aria-selected="false">Saled Items</a>
23 25
     <a class="nav-link" id="v-pills-vendor-tab" data-toggle="pill" data-bs-target="#v-pills-vendor" type="button" role="tab" aria-controls="v-pills-vendor" aria-selected="false">Vendors</a>
24 26
   </div>
25 27
   <div class="tab-content p-3 col-md-9 col-lg-10" id="v-pills-tabContent">
28
+      {% block breadcrumbs %}
29
+          {% clear_breadcrumbs %}
30
+          {% breadcrumb "My Store" "fruit:mystore" %}
31
+      {% endblock %}
32
+
33
+
34
+    {% render_breadcrumbs %} 
26 35
       {% block store_main %}
27 36
       {% endblock %}
28 37
   </div>

+ 36 - 30
app/fruit/templates/fruit/product_form.html

@@ -1,4 +1,4 @@
1
-{% extends "fruit/mystore.html" %}
1
+{% extends "fruit/product_index.html" %}
2 2
 {% load static %}
3 3
 {% load crispy_forms_tags %}
4 4
 
@@ -7,41 +7,47 @@
7 7
 {{ form2.media  }}
8 8
 {% endblock %}
9 9
 
10
+{% load django_bootstrap_breadcrumbs %}
11
+{% block breadcrumbs %}
12
+    {{ block.super }}
13
+    {% breadcrumb "Product Edit" "fruit:product_edit" pid  %}
14
+{% endblock %}
15
+
10 16
 {% block store_main %}
11 17
     Create Product
12 18
 
19
+
13 20
 <form  method="post" enctype="multipart/form-data">
14 21
     {% csrf_token %}
15 22
     {{ form | crispy  }}
16
-    <fieldset class="border p-2">
17
-        <legend class='w-auto d-inline-block form-legend p-3'>Photos</legend>
18
-        {{ form2.management_form }}
19
-        <div class='row'>
20
-        {% for f0  in form2 %}
21
-        <div class='col-md-3'>
22
-        <!-- {{ f0.fields }} -->
23
-
24
-            {{ f0.id  | as_crispy_field }}
25
-            {{ f0.name | as_crispy_field }}
26
-            {% if f0.instance.photo %}
27
-            <a href="{{ f0.instance.photo.url }}" target="_blank">
28
-                <img src="{{ f0.instance.photo.url  }}" width='100%' style='max-height:200px'></a>
29
-            {% endif %}
30
-            {{ f0.photo | as_crispy_field }}
31
-            
32
-            {{ f0.product | as_crispy_field }}
33
-            {{ f0.DELETE | as_crispy_field }}
34
-        </div>
35
-        {% endfor %}
36
-        </div>
37
-    </fieldset>
38
-    <br>
39
-    <input type='submit' class='btn btn-primary' name='updateStore' value="Update" />
23
+        <fieldset class="border p-2 row">
24
+            <legend class='w-auto d-inline-block form-legend p-3'>Photos</legend>
25
+            {{ form2.management_form }}
26
+            {% for f0  in form2 %}
27
+            <div class='col-md-3 border'>
28
+            <!-- {{ f0.fields }} -->
29
+
30
+                {{ f0.id  | as_crispy_field }}
31
+                {{ f0.name | as_crispy_field }}
32
+                {% if f0.instance.photo %}
33
+                <a href="{{ f0.instance.photo.url }}" target="_blank">
34
+                    <img src="{{ f0.instance.photo.url  }}" width='100%' style='max-height:200px'></a>
35
+                {% endif %}
36
+                {{ f0.photo | as_crispy_field }}
37
+                
38
+                {{ f0.order_n  | as_crispy_field }}
39
+                {{ f0.product | as_crispy_field }}
40
+                {{ f0.DELETE | as_crispy_field }}
41
+            </div>
42
+            {% endfor %}
43
+        </fieldset>
44
+        <br>
45
+        <input type='submit' class='btn btn-primary' name='updateStore' value="Update" />
40 46
 
41
-</form>
42
-<hr>
43
-<h2>SKUs</h2>
44
-<a href="{% url "fruit:create_sku" pk=object.pk %}" class='btn btn-primary'>Create SKU</a><br><br>
47
+    </form>
48
+    <hr>
49
+    <h2>SKUs</h2>
50
+    <a href="{% url "fruit:create_sku" pk=obj.pk %}" class='btn btn-primary'>Create SKU</a><br><br>
45 51
 
46 52
 <table class='table table-bordered  table-striped'>
47 53
     <thead>
@@ -50,7 +56,7 @@
50 56
     </thead>
51 57
     <tbody>
52 58
         
53
-        {% for o in  object.productsku_set.all %}
59
+        {% for o in  obj.productsku_set.all %}
54 60
             <tr>
55 61
                 <td><a href="{% url "fruit:edit_sku" pk=o.pk %}">{{ o.sku }}</a></td>
56 62
                 <td>{{ o.created_at }}</td>

+ 17 - 6
app/fruit/templates/fruit/product_index.html

@@ -5,21 +5,32 @@
5 5
 {% block header %}            
6 6
 {% endblock %}
7 7
 
8
+{% load django_bootstrap_breadcrumbs %}
9
+{% block breadcrumbs %}
10
+    {{ block.super }}
11
+    {% breadcrumb "Products" "fruit:product_index" %}
12
+{% endblock %}
13
+
8 14
 {% block store_main %}
9
-<a  href="{% url "fruit:product_create" %}">Create Product</a>
15
+<a  class='btn btn-primary' href="{% url "fruit:product_create" %}">Create Product</a>
16
+<hr>
17
+<h2>
18
+    Product Index</h2>
19
+{% include "fruit/_searchcenter.html" %}
10 20
 <hr>
11
-Product Index
12
-{{ products }}
21
+<!--
22
+    {{ products }} -->
13 23
 <table class='table table-borded table-striped'>
14 24
     <thead>
15
-        <tr><th>ID</th><th>Name</th><th>Created At</th></tr>
25
+        <tr><th>ID</th><th>Name</th><th>Price</th><th>Created At</th></tr>
16 26
     </thead>
17 27
     <tbody>
18
-{% for p in products %}
28
+{% for p in page_obj %}
19 29
         <tr>
20
-            <td><a href="{% url "fruit:product_edit" pk=p.pk %}">{{ p.id }}</a></td><td>{{ p.name }}</td><td>{{ p.created_at }}</td>
30
+            <td><a href="{% url "fruit:product_edit" pk=p.pk %}">{{ p.id }}</a></td><td>{{ p.name }}</td><td>{% firstof p.price  "-" %}</td><td>{{ p.created_at }}</td>
21 31
         </tr>
22 32
 {% endfor %}
23 33
     </tbody>
24 34
 </table>
35
+{% include "fruit/_paging.html" %}
25 36
 {% endblock %}

+ 25 - 0
app/fruit/templates/fruit/sale_form.html

@@ -0,0 +1,25 @@
1
+{% extends "fruit/sale_index.html" %}
2
+{% load static %}
3
+{% load crispy_forms_tags %}
4
+{% load django_bootstrap_breadcrumbs %}
5
+
6
+{% block header %}            
7
+{{ form.media  }}
8
+{% endblock %}
9
+
10
+{% block breadcrumbs %}
11
+    {{ block.super }}
12
+    {% breadcrumb "Sales Form" "fruit:sale_edit" form.instance.pk %}
13
+{% endblock %}
14
+
15
+{% block store_main %}
16
+<h2>Sale Form</h2>
17
+<form  method="post" enctype="multipart/form-data">
18
+    {% csrf_token %}
19
+    {{ form | crispy  }}
20
+    <br>
21
+    <input type='submit' class='btn btn-primary' value="Update" />
22
+
23
+</form>
24
+
25
+{% endblock %}

+ 41 - 0
app/fruit/templates/fruit/sale_index.html

@@ -0,0 +1,41 @@
1
+{% extends "fruit/mystore.html" %}
2
+{% load static %}
3
+{% load crispy_forms_tags %}
4
+
5
+{% block header %}            
6
+{% endblock %}
7
+
8
+{% load django_bootstrap_breadcrumbs %}
9
+{% block breadcrumbs %}
10
+    {{ block.super }}
11
+    {% breadcrumb "Sales" "fruit:sale_index" %}
12
+{% endblock %}
13
+
14
+{% block store_main %}
15
+<!--
16
+<a  class='btn btn-primary' href="{% url "fruit:product_create" %}">Create Product</a> -->
17
+<hr>
18
+<h2>
19
+    Sale Index</h2>
20
+{% include "fruit/_searchcenter.html" %}
21
+<hr>
22
+<table class='table table-borded table-striped'>
23
+    <thead>
24
+        <tr><th>ID</th><th>Product</th><th>SKU</th><th>Price</th><th>Unit(s)</th><th>UName</th><th>Total</th><th>Buyer</th><th>Created At</th></tr>
25
+    </thead>
26
+    <tbody>
27
+{% for p in page_obj %}
28
+        <tr>
29
+            <td><a href="{% url "fruit:sale_edit" pk=p.pk %}">{{ p.id }}</a></td><td>{{ p.product }}</td>
30
+            <td>{{ p.sku }}</td>
31
+            <td>{{ p.n_unit }}</td>
32
+            <td>{{ p.unit_name }}</td>
33
+            <td>{{ p.total }}</td>
34
+            <td>{{ p.buyer }}</td>
35
+            <td>{% firstof p.price  "-" %}</td><td>{{ p.created_at }}</td>
36
+        </tr>
37
+{% endfor %}
38
+    </tbody>
39
+</table>
40
+{% include "fruit/_paging.html" %}
41
+{% endblock %}

+ 7 - 1
app/fruit/templates/fruit/sku_form.html

@@ -1,4 +1,4 @@
1
-{% extends "fruit/mystore.html" %}
1
+{% extends "fruit/product_form.html" %}
2 2
 {% load static %}
3 3
 {% load crispy_forms_tags %}
4 4
 
@@ -6,6 +6,12 @@
6 6
 {{ form.media  }}
7 7
 {% endblock %}
8 8
 
9
+{% load django_bootstrap_breadcrumbs %}
10
+{% block breadcrumbs %}
11
+    {{ block.super }}
12
+    {% breadcrumb "SKU Edit" "fruit:sku_edit" pk=form.instance.pk  %}
13
+{% endblock %}
14
+
9 15
 {% block store_main %}
10 16
     SKU Form
11 17
 

+ 4 - 0
app/fruit/urls.py

@@ -11,6 +11,10 @@ urlpatterns = [
11 11
     path('sku/<pk>', views.edit_sku, name='edit_sku'),
12 12
     path('products/', views.product_index, name='product_index'),
13 13
     path('products/<pk>', views.product_edit, name='product_edit'),
14
+    path('sales/', views.sale_index, name='sale_index'),
15
+    path('sales/<pk>', views.sale_edit, name='sale_edit'),
16
+    path('inbox/', views.inbox_index, name='inbox_index'),
17
+    path('inbox/<pk>', views.inbox_edit, name='inbox_edit'),
14 18
     path('signup', views.signup, name='signup'),
15 19
 ]
16 20
 

+ 98 - 6
app/fruit/views.py

@@ -6,9 +6,10 @@ from django.contrib.auth.forms import UserCreationForm
6 6
 from django.urls import reverse
7 7
 from django.contrib.auth.decorators import login_required
8 8
 
9
-from fruit.models import Store, Product, Photo, ProductSKU
10
-from .forms import StoreForm, ProductForm, PhotoFormSet, InlinePhotoFormset, ProductSKUForm
9
+from fruit.models import Store, Product, Photo, ProductSKU, Sale, Inbox
10
+from .forms import StoreForm, ProductForm, InboxForm, SaleForm,  PhotoFormSet, InlinePhotoFormset, ProductSKUForm, ProductFilter, SaleFilter, InboxFilter
11 11
 from django.contrib import messages
12
+from django.core.paginator import Paginator
12 13
 
13 14
 
14 15
 def index(request):
@@ -48,7 +49,27 @@ def mystore(request):
48 49
 def product_index(request):
49 50
     stores = request.user.store_created.all().order_by("-created_at")
50 51
     products = stores[0].product_set.all().order_by("-created_at")
51
-    return render(request, 'fruit/product_index.html', {'products': products, 'product': True})
52
+
53
+    f = ProductFilter(request.GET, queryset=products)
54
+
55
+    paginator = Paginator(f.qs, 25)
56
+    page_number = request.GET.get('page')
57
+    page_obj = paginator.get_page(page_number)
58
+
59
+    return render(request, 'fruit/product_index.html', {'products': products, 'product': True, 'page_obj': page_obj, 'filter': f})
60
+
61
+@login_required
62
+def sale_index(request):
63
+    stores = request.user.store_created.all().order_by("-created_at")
64
+    o_qs = stores[0].sale_set.all().order_by("-created_at")
65
+
66
+    f = SaleFilter(request.GET, queryset=o_qs)
67
+
68
+    paginator = Paginator(f.qs, 25)
69
+    page_number = request.GET.get('page')
70
+    page_obj = paginator.get_page(page_number)
71
+
72
+    return render(request, 'fruit/sale_index.html', {'o_qs': o_qs, 'sale_active': True, 'page_obj': page_obj, 'filter': f})
52 73
 
53 74
 @login_required
54 75
 def create_product(request):
@@ -97,11 +118,14 @@ def create_sku(request, pk):
97 118
             message.error(request, "SKU  created failed")
98 119
             return redirect("fruit:create_sku", pk=int(pk))
99 120
 
100
-    return render(request, 'fruit/sku_form.html', {'form': form})
121
+    return render(request, 'fruit/sku_form.html', {'form': form, 'pid': p.pk})
101 122
 
102 123
 @login_required
103 124
 def edit_sku(request, pk):
125
+
104 126
     p = ProductSKU.objects.get(pk=pk)
127
+    p0 = p.product
128
+
105 129
     form = ProductSKUForm(instance=p)
106 130
     if request.method == "POST":
107 131
         form = ProductSKUForm(request.POST)
@@ -113,7 +137,7 @@ def edit_sku(request, pk):
113 137
             message.error(request, "SKU  created failed")
114 138
             return redirect("fruit:create_sku", pk=int(pk))
115 139
 
116
-    return render(request, 'fruit/sku_form.html', {'form': form})
140
+    return render(request, 'fruit/sku_form.html', {'form': form, 'pid': p0.pk})
117 141
 
118 142
 @login_required
119 143
 def product_edit(request, pk):
@@ -151,7 +175,75 @@ def product_edit(request, pk):
151 175
 
152 176
         return redirect("fruit:product_edit", pk =  int(pk))
153 177
 
154
-    return render(request, 'fruit/product_form.html', {'product': True, 'form': form, 'form2': form2, 'object': product })
178
+    return render(request, 'fruit/product_form.html', {'product': True, 'form': form, 'form2': form2, 'obj': product })
179
+
180
+@login_required
181
+def sale_edit(request, pk):
182
+    stores = request.user.store_created.all().order_by("-created_at")
183
+
184
+    obj = Sale.objects.get(pk=pk)
185
+    form = SaleForm(instance = obj)
186
+
187
+    if request.method == "POST":
188
+        form = SaleForm(request.POST)
189
+        if form.is_valid():
190
+            instance1 = form.save()
191
+            '''
192
+            print(instances)
193
+            for s in instances:
194
+                s.product = instance1
195
+                s.save()
196
+            '''
197
+            messages.success(request, "Sale Save")
198
+        else:
199
+            print("Invalid ")
200
+            if form.errors:
201
+                messages.error(request, form.errors)
202
+
203
+        return redirect("fruit:sale_edit", pk =  int(pk))
204
+
205
+    return render(request, 'fruit/sale_form.html', {'sale_active': True, 'form': form, 'object': obj})
206
+
207
+
208
+@login_required
209
+def inbox_index(request):
210
+    stores = request.user.store_created.all().order_by("-created_at")
211
+    o_qs = stores[0].inbox_set.all().order_by("-created_at")
212
+
213
+    f = InboxFilter(request.GET, queryset=o_qs)
214
+
215
+    paginator = Paginator(f.qs, 25)
216
+    page_number = request.GET.get('page')
217
+    page_obj = paginator.get_page(page_number)
218
+
219
+    return render(request, 'fruit/inbox_index.html', {'o_qs': o_qs, 'inbox_active': True, 'page_obj': page_obj, 'filter': f})
220
+
221
+@login_required
222
+def inbox_edit(request, pk):
223
+    stores = request.user.store_created.all().order_by("-created_at")
224
+
225
+    obj = Inbox.objects.get(pk=pk)
226
+    form = InboxForm(instance = obj)
227
+
228
+    if request.method == "POST":
229
+        form = InboxForm(request.POST)
230
+        if form.is_valid():
231
+            instance1 = form.save()
232
+            '''
233
+            print(instances)
234
+            for s in instances:
235
+                s.product = instance1
236
+                s.save()
237
+            '''
238
+            messages.success(request, "Sale Save")
239
+        else:
240
+            print("Invalid ")
241
+            if form.errors:
242
+                messages.error(request, form.errors)
243
+
244
+        return redirect("fruit:sale_edit", pk =  int(pk))
245
+
246
+    return render(request, 'fruit/inbox_form.html', {'inbox_active': True, 'form': form, 'object': obj})
155 247
 
156 248
 def signup(request):
157 249
     if request.method == 'POST':

+ 3 - 0
app/requirements.txt

@@ -14,3 +14,6 @@ Pillow
14 14
 django-quill-editor
15 15
 django-taggit
16 16
 django-crispy-forms
17
+django-filter
18
+django-paypal
19
+django-bootstrap-breadcrumbs

BIN
app/shaqfindbed/__pycache__/settings.cpython-39.pyc


+ 3 - 0
app/shaqfindbed/settings.py

@@ -47,12 +47,14 @@ INSTALLED_APPS = [
47 47
     'dal_select2',
48 48
     'mptt',
49 49
     'django_google_maps',
50
+    'django_bootstrap_breadcrumbs',
50 51
     'django.contrib.admin',
51 52
     'django.contrib.auth',
52 53
     'django.contrib.contenttypes',
53 54
     'django.contrib.sessions',
54 55
     'django.contrib.messages',
55 56
     'import_export',
57
+    'django_filters',
56 58
     'django_quill',
57 59
     'crispy_forms',
58 60
     'taggit',
@@ -171,3 +173,4 @@ LOGIN_REDIRECT_URL = '/fruit/mystore'
171 173
 LOGIN_URL = '/login'
172 174
 
173 175
 CRISPY_TEMPLATE_PACK = "bootstrap4"
176
+BREADCRUMBS_TEMPLATE = "django_bootstrap_breadcrumbs/bootstrap4.html"

tum/network_report_server - Gogs: Simplico Git Service

Нет описания

wrapperAt.js 1.3KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849
  1. var LazyWrapper = require('./_LazyWrapper'),
  2. LodashWrapper = require('./_LodashWrapper'),
  3. baseAt = require('./_baseAt'),
  4. flatRest = require('./_flatRest'),
  5. isIndex = require('./_isIndex'),
  6. thru = require('./thru');
  7. /**
  8. * This method is the wrapper version of `_.at`.
  9. *
  10. * @name at
  11. * @memberOf _
  12. * @since 1.0.0
  13. * @category Seq
  14. * @param {...(string|string[])} [paths] The property paths to pick.
  15. * @returns {Object} Returns the new `lodash` wrapper instance.
  16. * @example
  17. *
  18. * var object = { 'a': [{ 'b': { 'c': 3 } }, 4] };
  19. *
  20. * _(object).at(['a[0].b.c', 'a[1]']).value();
  21. * // => [3, 4]
  22. */
  23. var wrapperAt = flatRest(function(paths) {
  24. var length = paths.length,
  25. start = length ? paths[0] : 0,
  26. value = this.__wrapped__,
  27. interceptor = function(object) { return baseAt(object, paths); };
  28. if (length > 1 || this.__actions__.length ||
  29. !(value instanceof LazyWrapper) || !isIndex(start)) {
  30. return this.thru(interceptor);
  31. }
  32. value = value.slice(start, +start + (length ? 1 : 0));
  33. value.__actions__.push({
  34. 'func': thru,
  35. 'args': [interceptor],
  36. 'thisArg': undefined
  37. });
  38. return new LodashWrapper(value, this.__chain__).thru(function(array) {
  39. if (length && !array.length) {
  40. array.push(undefined);
  41. }
  42. return array;
  43. });
  44. });
  45. module.exports = wrapperAt;