-num lines-num-old"> 8
+{% if results %}
9
+<h1 class='text-center mt-4 mb-4'>Search Results</h1>
10
+<div class='card-columns'>
11
+{% for r in results %}
12
+<div class="card">
13
+    {% if  r|className == "Post" %}
14
+    <img src="{{ r.featureImage.url }}" class="card-img-top" alt="...">
15
+    <div class="card-body">
16
+        <h5 class="card-title">
17
+            <a href="{% url "front:viewPost"   pid=r.id  %}?cstr={{ r.store.id }}">{{ r.title }}</a>
18
+        </h5>
19
+        <p class="card-text">
20
+        {{ r.description }}</p>
21
+        <p class="card-text"><small class="text-muted">{{ r.created_at }}</small></p>
22
+    </div>
23
+    {% endif %}
24
+</div>
25
+{% endfor %}
26
+</div>
27
+{% else %}
28
+<h1 class='text-center mt-4 mb-4'>Your Search not Matched any Records</h1>
29
+{% endif %}
30
+{% endblock %}

+ 77 - 0
app/front/templates/front/storeContact.html

@@ -0,0 +1,77 @@
1
+{% extends "front/storeFront.html" %}
2
+{% load mptt_tags %}
3
+{% load static %}
4
+{% load crispy_forms_tags %}
5
+
6
+{% block content %}
7
+<h1>{{ storeFront.fullName }}</h1>
8
+<div class='row'>
9
+    <div class='col-md-9'>
10
+        <p>
11
+        {{ storeFront.description }}
12
+        </p>
13
+        <div id='map'>
14
+        </div>
15
+    </div>
16
+    <div class='col-md-3'>
17
+        <dl>
18
+            <dt>Address</dt>
19
+            <dd>
20
+        {{ storeFront.addressText }}
21
+            </dd>
22
+            <dt>Tel</dt>
23
+            <dd>
24
+                <a href="callto:{{ storeFront.tel_number }}">
25
+                    {{ storeFront.tel_number}}
26
+                </a>
27
+            </dd>
28
+            <dt>Fax</dt>
29
+            <dd>
30
+                <a href="callto:{{ storeFront.fax_number }}">
31
+                    {{ storeFront.fax_number }}</a>
32
+            </dd>
33
+            <dt>LineID</dt>
34
+            <dd>
35
+                <a href="https://line.me/R/{{ storeFront.lineId }}">
36
+                    {{ storeFront.lineId }}</a>
37
+            </dd>
38
+            <dt>Email</dt>
39
+            <dd>
40
+                <a href="mailto:{{ storeFront.email }}">
41
+                    {{ storeFront.email }}</a>
42
+            </dd>
43
+        </dl>
44
+    </div>
45
+</div>
46
+{% endblock %}
47
+
48
+{% block header_script %}
49
+<style type='text/css'>
50
+#map {
51
+  height: 600px;
52
+}
53
+
54
+</style>
55
+{% endblock %}
56
+
57
+{% block foot_script %}
58
+    <script type='text/javascript'>
59
+        let map;
60
+
61
+        function initMap() {
62
+                let latLng = {lat: {{ geo.lat }}, lng: {{ geo.lon }} }; 
63
+                map = new google.maps.Map(document.getElementById("map"), {
64
+                    center: latLng,
65
+                    zoom: 8,
66
+                });
67
+                new google.maps.Marker({
68
+                        position: latLng,
69
+                        map,
70
+                        title: "{{ storeFront.fullName }}",
71
+                });
72
+        }
73
+                //initMap();
74
+        window.initMap = initMap;
75
+
76
+    </script>
77
+{% endblock %}

+ 34 - 0
app/front/templates/front/storeFront.html

@@ -0,0 +1,34 @@
1
+{% extends "front/base.html" %}
2
+{% load mptt_tags %}
3
+{% load static %}
4
+{% load crispy_forms_tags %}
5
+
6
+{% block content %}
7
+{% include "front/_localSearch.html" %}
8
+{% if storeFront %}
9
+
10
+<div class="card mb-3">
11
+    <div class="row no-gutters">
12
+        <div class="col-md-4">
13
+            {% if storeFront.logo %}
14
+            <img src="{{ storeFront.logo }}" class="rounded-circle" alt="Cinque Terre">
15
+            {% endif %}
16
+        </div>
17
+        <div class="col-md-8">
18
+            <div class="card-body">
19
+                <h5 class="card-title">{{ storeFront.fullName }}</h5>
20
+                <p class="card-text">
21
+                    {% firstof storeFront.description " " %}
22
+                </p>
23
+                <a class='btn btn-primary btn-sm' href="{% url  "front:viewStoreMap" %}?cstr={{ storeFront.storeId }}" target="_blank">View Map</a>
24
+                <a class='btn btn-danger btn-sm' href="">Follow</a>
25
+                <a class='btn btn-secondary btn-sm' href="">Share</a>
26
+            </div>
27
+        </div>
28
+    </div>
29
+</div>
30
+{% endif %}
31
+{% include "front/_promotions.html" with objs=promotions %}
32
+{% include "front/_recs.html" with objs=recs %}
33
+{% include "front/_reviews.html" with objs=reviews %}
34
+{% endblock %}

+ 95 - 0
app/front/templates/front/storeMap.html

@@ -0,0 +1,95 @@
1
+{% extends "front/storeFront.html" %}
2
+{% load mptt_tags %}
3
+{% load static %}
4
+{% load crispy_forms_tags %}
5
+
6
+{% block content %}
7
+<h1>{{ storeFront.fullName }}</h1>
8
+<div class='row'>
9
+    <div class='col-md-9'>
10
+        <p>
11
+        {{ storeFront.description }}
12
+        </p>
13
+        <form method='post' enctype="multipart/form-data" >
14
+            {% csrf_token %}
15
+            <div class="card w-100">
16
+                 <div class="card-header">Contact Us</div>
17
+                <div class="card-body">
18
+            <div class="row">
19
+            <div class="col-md-6">{{ form.subject | as_crispy_field }}</div>
20
+            <div class="col-md-6">{{ form.email | as_crispy_field }}</div>
21
+            <div class="col-md-6">{{ form.tel | as_crispy_field }}</div>
22
+            <div class="col-md-6">{{ form.lineId | as_crispy_field }}</div>
23
+            <div class="col-md-12">{{ form.body | as_crispy_field }}</div>
24
+            <div class="col-md-12">{{ form.messageFile | as_crispy_field }}</div>
25
+            </div>
26
+            <input type='submit' value='Save' class='btn btn-primary btn-block'>
27
+                </div>
28
+            </div>
29
+        </form>
30
+        <hr>
31
+        <div id='map'>
32
+        </div>
33
+    </div>
34
+    <div class='col-md-3'>
35
+        <dl>
36
+            <dt>Address</dt>
37
+            <dd>
38
+        {{ storeFront.addressText }}
39
+            </dd>
40
+            <dt>Tel</dt>
41
+            <dd>
42
+                <a href="callto:{{ storeFront.tel_number }}">
43
+                    {{ storeFront.tel_number}}
44
+                </a>
45
+            </dd>
46
+            <dt>Fax</dt>
47
+            <dd>
48
+                <a href="callto:{{ storeFront.fax_number }}">
49
+                    {{ storeFront.fax_number }}</a>
50
+            </dd>
51
+            <dt>LineID</dt>
52
+            <dd>
53
+                <a href="https://line.me/R/{{ storeFront.lineId }}">
54
+                    {{ storeFront.lineId }}</a>
55
+            </dd>
56
+            <dt>Email</dt>
57
+            <dd>
58
+                <a href="mailto:{{ storeFront.email }}">
59
+                    {{ storeFront.email }}</a>
60
+            </dd>
61
+        </dl>
62
+    </div>
63
+</div>
64
+{% endblock %}
65
+
66
+{% block header_script %}
67
+<style type='text/css'>
68
+#map {
69
+  height: 600px;
70
+}
71
+
72
+</style>
73
+{% endblock %}
74
+
75
+{% block foot_script %}
76
+    <script type='text/javascript'>
77
+        let map;
78
+
79
+        function initMap() {
80
+                let latLng = {lat: {{ geo.lat }}, lng: {{ geo.lon }} }; 
81
+                map = new google.maps.Map(document.getElementById("map"), {
82
+                    center: latLng,
83
+                    zoom: 8,
84
+                });
85
+                new google.maps.Marker({
86
+                        position: latLng,
87
+                        map,
88
+                        title: "{{ storeFront.fullName }}",
89
+                });
90
+        }
91
+                //initMap();
92
+        window.initMap = initMap;
93
+
94
+    </script>
95
+{% endblock %}

+ 18 - 0
app/front/templates/front/viewPost.html

@@ -0,0 +1,18 @@
1
+{% extends "front/storeFront.html" %}
2
+{% load mptt_tags %}
3
+{% load static %}
4
+{% load crispy_forms_tags %}
5
+
6
+{% block content %}
7
+<h1>{{ post.title }}</h1>
8
+<div class='row'>
9
+    <div class='col-md-9'>
10
+        <div class='content-wrap'>
11
+            {{ post.content | safe  }}
12
+        </div>
13
+    {% include "front/_relate_menus.html" with objs=post.relateMenus.all %}
14
+    </div>
15
+    <div class='col-md-3'>
16
+    </div>
17
+</div>
18
+{% endblock %}

+ 3 - 0
app/front/tests.py

@@ -0,0 +1,3 @@
1
+from django.test import TestCase
2
+
3
+# Create your tests here.

+ 16 - 0
app/front/urls.py

@@ -0,0 +1,16 @@
1
+from django.urls import path
2
+
3
+from . import views
4
+
5
+urlpatterns = [
6
+    path('', views.index, name='index'),
7
+    path('search', views.search, name='search'),
8
+    path('myStore', views.myStore, name='myStore'),
9
+    path('store', views.storeFrontView, name='storeFront'),
10
+    path('store/<storeId>/menus', views.storeMenus, name='viewStoreMenus'),
11
+    path('menus/<menuId>', views.viewMenu, name='viewMenu'),
12
+    path('store/posts/<pid>', views.viewPost, name='viewPost'),
13
+    path('store/map', views.viewStoreMap, name='viewStoreMap'),
14
+    path('store/contact', views.storeContact, name='storeContact'),
15
+]
16
+app_name = 'front'

+ 87 - 0
app/front/views.py

@@ -0,0 +1,87 @@
1
+from django.shortcuts import render, redirect, reverse
2
+from django.contrib.auth.decorators import login_required
3
+from pos.pos import PosSys
4
+from pos.storefront import StoreFront
5
+from django.http import JsonResponse
6
+from django.contrib import messages
7
+# Create your views here.
8
+def index(request):
9
+    return render(request,'front/index.html')
10
+
11
+@login_required
12
+def myStore(request):
13
+    pos = PosSys.restoreStore(request.user)
14
+    storeInfo = pos.uiSys.renderStoreInfo()
15
+    primaryMenu = pos.uiSys.menu('primary')
16
+    formInstance = pos.uiSys.form('tableForm')
17
+
18
+    print("Instance")
19
+    print(formInstance)
20
+
21
+    if request.method == "POST":
22
+        formInstance = pos.uiSys.form('tableForm', request=request)
23
+        if formInstance.is_valid():
24
+            formInstance.save()
25
+            print("valid")
26
+        else:
27
+            print(formInstance.errors)
28
+            print("invalide")
29
+        return redirect('front:myStore')
30
+
31
+    return render(request, 'front/mystore.html', {'pos': pos, 'storeInfo': storeInfo, 'primaryMenu': primaryMenu, 'form': formInstance})
32
+
33
+def storeFrontView(request):
34
+    if request.storeFront:
35
+        menus = request.storeFront.getMenus()[:10]
36
+        promotions = request.storeFront.getPosts(cat='Promotions')
37
+        recs = request.storeFront.getPosts(cat="Recommendations")
38
+        reviews = request.storeFront.getPosts(cat="Reviews")
39
+        return render(request, 'front/storeFront.html', {'promotions': promotions, 'recs': recs, 'reviews': reviews, 'menus': menus})
40
+    return JsonResponse({'msg': "Please provide store id in querystring"})
41
+
42
+
43
+def storeMenus(request, storeId):
44
+    return render(request, 'front/storeMenus.html')
45
+
46
+def viewMenu(request, menuId):
47
+    return render(request, 'front/viewMenu.html')
48
+
49
+def viewPost(request, pid):
50
+    post = request.storeFront.getPostById(pid)
51
+    return render(request, 'front/viewPost.html', {'post': post})
52
+
53
+def viewStoreMap(request):
54
+    location = request.storeFront.location
55
+    form = request.storeFront.messageForm()
56
+    if request.method == 'POST':
57
+        form = request.storeFront.messageForm(request=request)
58
+        if form.is_valid():
59
+            o = form.save(commit=False)
60
+            o.store = request.storeFront.store
61
+            o.save()
62
+            messages.success(request, 'Thank you for your contact')
63
+            return redirect(reverse('front:viewStoreMap')+f"?cstr={request.storeFront.storeId}")
64
+    return render(request, 'front/storeMap.html', {'geo': location[1], 'address': location[0], 'form': form})
65
+
66
+
67
+def storeContact(request):
68
+    form = request.storeFront.messageForm()
69
+    if request.method == 'POST':
70
+        form = request.storeFront.messageForm(request=request)
71
+        if form.is_valid():
72
+            o = form.save()
73
+            messages.success(request, 'Thank you for your contact')
74
+            return redirect(reverse('front:storeContact')+"?cstr="+request.storeFront.storeId)
75
+    return render(request, 'front/storeContact.html', {'form': form})
76
+
77
+def search(request):
78
+    results  = None
79
+    q = request.GET.get('q', '')
80
+    print(q)
81
+    if request.storeFront:
82
+        results = request.storeFront.search(q=q)
83
+    else:
84
+        results = StoreFront.globalSearch(q)
85
+        print(results)
86
+    return render(request, 'front/search.html', {'results': results})
87
+

+ 28 - 0
app/key.pem

@@ -0,0 +1,28 @@
1
+-----BEGIN PRIVATE KEY-----
2
+MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDM7eQObxKic7Y/
3
++lI5CYU9iiPb5/PycR3myz68v95FzkFomyrXrnWCUh07JRfXcHgTS+JMXRprpI/2
4
+NktTqU+W4nBblRgK5VJbrvAvQS8LzZMGkHPaEwa4LoNykbScmDNjTiS7PSYlqpa1
5
+YPgAyrcE7CAE3LY+sHjlxQYEF7du+wKKn3KRVby8cRYqAel2dm9Ridttt5r2MNH+
6
+cHRwN4p3krjlX8u/YQIEAZrbvYL1r26pe7MhxUWx05v2yzpg3KJKzUAl5dNXXozm
7
+7pmVU33khT0AepbF5MJVjIZlZm2DVcPswH8zbb+YNSNmDV90re/af5EXHKj8Uag0
8
+TrOIALPrAgMBAAECggEBALGtmMwC9c8wMFYsPVoCrSl8OjcSV2pfNSPEGLMiUB+K
9
+AyAlWPID6xKBC6MaOB+s/g8M/jpjhuLJnaBF1u3EoKMb1XsyO9RGnC+t78Wo6Jd9
10
+N/q7CBeN44eRnJqbRlN3iyaQvDwzen2x+FVuq9hT6nc0G1bb3o9gBpKBTwQBZCOt
11
+o4djb1dkSx3qB917VC4+0yK1pknliANxxdVcq8ZHfcY3G7xkgV8crn5UB95HmFAp
12
+9sJ1XxpXHqoD+lgLakQKhgHOTqQdb0mbMOPkHA5Zw2YRV89FaYc2m+if3rWyaK4z
13
+yk9hSd8/LK71rmYO0YlVDGwWkhUkDAD3q/T20kpeFxECgYEA/Uf5PqKc3Z9k6bTp
14
+3JnfMNrXY4Nk1pE8apZF1Saho8mKsCX0Vm3x4DC8xZgwE5gvMusopHWp/EoCvMet
15
+5/EJpNXzjLZB35IdAiGCYQPLEQTQjmCtsQIRoknhZc9nKPw/iWlev68Yrrf16jkj
16
+9FrvyyFEWQ4wUgQftPC/7u5Ad58CgYEAzyELXIxtXpXdjch0X9L7IRULuQ4Rs7q3
17
+7+TvFYd5P0X2zBBJ7AHjamaru7C+ytnT7bpSudRv36k9KySsHtqGKl9uSJrGGJeW
18
+kqQ9wOorwu9PDVvdL2DxG31bK5b+BcQhqSPYJEVe3FpETJgtbFNIIf9LEVg73v91
19
+iNiNqbwSEDUCgYEAq7poCQrSVwWisz7BrZv6kzJeBY/qB/1TPGWFFZ9qyxV0Xjht
20
+sUg8TihdZY/pUO/HWLvOw6svxOodbwfoJrHsOwIBbu+IPGDiIDa+Iq8iuPhNu6tb
21
+OP/RGvsCwzfblxNotO9nmYnLr3L1Xoi9kwkxOsXkhIk1Q/ad1N3DFOofdbsCgYAq
22
+X2kymqu5INF9MtfTzpZ/Uw3d4qnuabE9S0k5z0gXkJmHb4Gf3VcHqk9RizvMxbkc
23
+NfS8fWARkk6oJ81qVmwB+RnXkooZ99De2OilMYKYU1qJshRSn/NTG1buWOpIhbIZ
24
+JvMNoH9idrjoLm2EbpkgE1jpCHLfEMWbpCl+4rGTTQKBgQCvOqqWpwS0fJFwbx1h
25
+F+jcLf9eQHD5B/kh91f4dvB3Uywi2vP5pkAPkRS2dd6z5ZKNuHCCUYizKDR6d20g
26
+EnGUuN96uyby4vT5Xar1/6IWcJl2VpjHAUjGAKw2PHRA4ti+RO7oo4TP9J/tF/Ec
27
+xoO0p1jYKttMAiKBlw10sNBZmg==
28
+-----END PRIVATE KEY-----

+ 22 - 0
app/manage.py

@@ -0,0 +1,22 @@
1
+#!/usr/bin/env python
2
+"""Django's command-line utility for administrative tasks."""
3
+import os
4
+import sys
5
+
6
+
7
+def main():
8
+    """Run administrative tasks."""
9
+    os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'simpliPos.settings')
10
+    try:
11
+        from django.core.management import execute_from_command_line
12
+    except ImportError as exc:
13
+        raise ImportError(
14
+            "Couldn't import Django. Are you sure it's installed and "
15
+            "available on your PYTHONPATH environment variable? Did you "
16
+            "forget to activate a virtual environment?"
17
+        ) from exc
18
+    execute_from_command_line(sys.argv)
19
+
20
+
21
+if __name__ == '__main__':
22
+    main()

BIN
app/mycert.cer


+ 0 - 0
app/pos/__init__.py


+ 70 - 0
app/pos/admin.py

@@ -0,0 +1,70 @@
1
+from django.contrib import admin
2
+from .models import Store, MenuItem, Setting, StoreFile, Table, BookingTable, Order,  MenuFile, OrderItem, UIMenu, PostCategory, Post
3
+from django_better_admin_arrayfield.admin.mixins import DynamicArrayMixin
4
+from mptt.admin import MPTTModelAdmin
5
+from django_admin_hstore_widget.forms import HStoreFormField
6
+
7
+from django.contrib.postgres.fields import HStoreField, ArrayField
8
+
9
+from django import forms
10
+
11
+
12
+
13
+
14
+# Register your models here.
15
+
16
+class StoreFileAdmin(admin.TabularInline):
17
+    model = StoreFile
18
+
19
+class MenuItemAdmin(admin.StackedInline):
20
+    model = MenuItem
21
+
22
+class OrderItemAdmin(admin.TabularInline):
23
+    model = OrderItem
24
+
25
+class StoreAdmin(admin.ModelAdmin):
26
+   inlines = [StoreFileAdmin, MenuItemAdmin]
27
+   formfield_overrides = {
28
+        HStoreField: {'widget': HStoreFormField},
29
+    }
30
+
31
+class SettingAdmin(admin.ModelAdmin):
32
+    pass
33
+
34
+class OrderAdmin(admin.ModelAdmin):
35
+   inlines = [OrderItemAdmin,]
36
+
37
+
38
+class SettingAdminForm(forms.ModelForm):
39
+    data = HStoreFormField()
40
+
41
+    class Meta:
42
+       model = Setting
43
+       exclude = ()
44
+
45
+@admin.register(Setting)
46
+class SettingAdmin(admin.ModelAdmin):
47
+    form = SettingAdminForm
48
+
49
+@admin.register(Post)
50
+class PostAdmin(admin.ModelAdmin):
51
+    list_display = ('title', 'tag_list', 'cats', 'created_at', 'store', 'featureImage')
52
+    save_as = True
53
+
54
+    def tag_list(self, obj):
55
+        return u", ".join(o.name for o in obj.tags.all())
56
+
57
+
58
+admin.site.register(Store, StoreAdmin)
59
+admin.site.register(MenuItem)
60
+#admin.site.register(Setting, SettingAdmin)
61
+admin.site.register(StoreFile)
62
+admin.site.register(Table)
63
+admin.site.register(BookingTable)
64
+admin.site.register(Order, OrderAdmin)
65
+admin.site.register(MenuFile)
66
+admin.site.register(UIMenu, MPTTModelAdmin)
67
+#admin.site.register(Post)
68
+admin.site.register(PostCategory, MPTTModelAdmin)
69
+
70
+

+ 6 - 0
app/pos/apps.py

@@ -0,0 +1,6 @@
1
+from django.apps import AppConfig
2
+
3
+
4
+class PosConfig(AppConfig):
5
+    default_auto_field = 'django.db.models.BigAutoField'
6
+    name = 'pos'

+ 53 - 0
app/pos/context_processors.py

@@ -0,0 +1,53 @@
1
+from django.conf import settings
2
+from .pos import PosSys
3
+from .storefront import StoreFront
4
+import json
5
+from .models import Store
6
+
7
+def pos(request):
8
+    store = Store.objects.get(pk=settings.STORE_ID)
9
+    cstr = request.GET.get('cstr', None)
10
+    if cstr:
11
+        storeFront = StoreFront(int(cstr))
12
+    else:
13
+        storeFront = None
14
+
15
+    if hasattr(request, 'user') and request.user.is_authenticated:
16
+        user = request.user
17
+        pos = PosSys.restoreStore(user)
18
+        storeInfo = pos.uiSys.renderStoreInfo()
19
+
20
+        #ms = jso.loads(pos.settingSys.get('menus'))
21
+        ms = []
22
+        try:
23
+            ms = json.loads(pos.settingSys.get('menus'))
24
+        except TypeError:
25
+            ms = []
26
+
27
+        print(ms)
28
+        print(type(ms))
29
+        temp = []
30
+        for i in ms:
31
+            temp.append({'title': i['title'], 'menu': pos.uiSys.menu(i['name'])})
32
+            #ms.append(pos.uiSys.menu(m))
33
+
34
+        ctx  = {
35
+            'pos': pos,
36
+            'info': storeInfo,
37
+            'menus': temp,
38
+            'primaryMenu': pos.uiSys.menu('primary'),
39
+            'store': store,
40
+            'storeFront': storeFront,
41
+        }
42
+        return ctx
43
+    else:
44
+        ctx = {
45
+            'pos': None,
46
+            'info': None,
47
+            'menus': [],
48
+            'store': store,
49
+            'storeFront': storeFront,
50
+        }
51
+        return ctx
52
+
53
+

+ 159 - 0
app/pos/forms.py

@@ -0,0 +1,159 @@
1
+from pos.models import MenuItem, Store, Setting, Table, BookingTable, Order, OrderItem, UIMenu, Post, PostCategory, Customer, Code, Profile, Message
2
+
3
+from django.forms import ModelForm
4
+import django_filters
5
+
6
+from django.forms import BaseInlineFormSet, DateField, TimeField, TextInput, ModelMultipleChoiceField, CheckboxSelectMultiple
7
+
8
+from mptt.forms import TreeNodeMultipleChoiceField
9
+from django_editorjs_fields import EditorJsWidget
10
+from django.contrib.auth.models import User
11
+from django_google_maps.widgets import GoogleMapsAddressWidget
12
+
13
+class TableForm(ModelForm):
14
+    class Meta:
15
+        model = Table
16
+        fields = ('code', 'nSeats', 'occupy',)
17
+
18
+class MessageForm(ModelForm):
19
+    class Meta:
20
+        model = Message
21
+        fields = ('subject', 'email', 'tel', 'body', 'messageFile', 'lineId', 'reply', 'parent', )
22
+
23
+class UIMenuForm(ModelForm):
24
+    class Meta:
25
+        model = UIMenu
26
+        fields = ('name', 'parent', 'group', 'url', 'icon', 'nOrder', )
27
+
28
+class OrderForm(ModelForm):
29
+    class Meta:
30
+        model = Order
31
+        fields = '__all__'
32
+
33
+class PostForm(ModelForm):
34
+    #category = TreeNodeMultipleChoiceField(queryset=PostCategory.objects.all())
35
+    '''
36
+    relateMenus = ModelMultipleChoiceField(
37
+        queryset=MenuItem.objects.all(),
38
+        widget=CheckboxSelectMultiple,
39
+        required=False)
40
+    '''
41
+
42
+    class Meta:
43
+        model = Post
44
+        fields = ('featureImage', 'title', 'content', 'description', 'category', 'tags', 'relateMenus' )
45
+
46
+class CustomerForm(ModelForm):
47
+    #category = TreeNodeMultipleChoiceField(queryset=PostCategory.objects.all())
48
+
49
+    class Meta:
50
+        model = Customer
51
+        fields = ('fullName', 'email', 'lineId', 'gender', )
52
+
53
+class BookingForm(ModelForm):
54
+    onDate = DateField(
55
+        widget=TextInput(
56
+            attrs={'type': 'date'}
57
+        )
58
+    )
59
+    onTime = TimeField(
60
+        widget=TextInput(
61
+            attrs={'type': 'time'}
62
+        )
63
+    )
64
+    class Meta:
65
+        model = BookingTable
66
+        fields = ('table', 'onDate',  'onTime', 'note',)
67
+
68
+class MenuItemForm(ModelForm):
69
+    class Meta:
70
+        model = MenuItem
71
+        fields = ['featureImage', 'name', ]
72
+
73
+class StoreForm(ModelForm):
74
+    class Meta:
75
+        model = Store
76
+        fields = ['logo', 'name','description', 'addressText', 'province','address',  'phone_number', 'fax_number', 'lineId',  'email', 'geolocation',  'storeType']
77
+
78
+        widgets = {
79
+            "address": GoogleMapsAddressWidget,
80
+        }
81
+
82
+class OrderItemFormSet(BaseInlineFormSet):
83
+    def __init__(self, other_model_queryset, *args, **kwargs):
84
+        super(BaseInlineFormSet, self).__init__(*args)
85
+
86
+        for form in self.forms:
87
+            form.fields['item'].queryset = other_model_queryset
88
+
89
+
90
+formMap = {
91
+    'tableForm': TableForm
92
+}
93
+
94
+class OrderFilter(django_filters.FilterSet):
95
+    note = django_filters.CharFilter(lookup_expr='iexact')
96
+
97
+    class Meta:
98
+        model = Order
99
+        fields = ['table', 'note']
100
+
101
+class MenuItemFilter(django_filters.FilterSet):
102
+    class Meta:
103
+        model = MenuItem
104
+        fields = ['name', ]
105
+
106
+class StoreFilter(django_filters.FilterSet):
107
+    class Meta:
108
+        model = Store
109
+        fields = ('name', 'address', 'province','storeType')
110
+
111
+class BookingFilter(django_filters.FilterSet):
112
+    class Meta:
113
+        model = BookingTable
114
+        fields = ('table', 'onDate', 'note', )
115
+
116
+class CustomerFilter(django_filters.FilterSet):
117
+    class Meta:
118
+        model = Customer
119
+        fields = ('fullName', 'email', 'lineId', 'gender', 'created_at', )
120
+
121
+class TableFilter(django_filters.FilterSet):
122
+    class Meta:
123
+        model = Table
124
+        fields = ('code', 'nSeats', 'occupy', )
125
+
126
+class UIMenuFilter(django_filters.FilterSet):
127
+    class Meta:
128
+        model = UIMenu
129
+        fields = ('name', 'parent', 'group', 'url', 'icon','nOrder')
130
+
131
+class MessageFilter(django_filters.FilterSet):
132
+    class Meta:
133
+        model = Message
134
+        fields = ('subject', 'email', 'tel', 'body', 'reply', 'parent', 'created_at',  )
135
+
136
+class PostFilter(django_filters.FilterSet):
137
+    class Meta:
138
+        model = Post
139
+        fields = ('title', 'content', )
140
+
141
+class UserFilter(django_filters.FilterSet):
142
+    profile__role = django_filters.ChoiceFilter(label="Role", choices=Profile.ROLE_CHOICES)
143
+
144
+    class Meta:
145
+        model = User
146
+        fields = ('username', 'first_name', 'last_name', 'email', )
147
+
148
+
149
+
150
+
151
+class CodeForm(ModelForm):
152
+    class Meta:
153
+        model = Code
154
+        exclude = ['store', 'owner',]
155
+        widgets = {
156
+            'body_editorjs': EditorJsWidget(config={'minHeight': 100}),
157
+            'body_editorjs_text': EditorJsWidget(plugins=["@editorjs/image", "@editorjs/header"]),
158
+        }
159
+

+ 22 - 0
app/pos/middleware.py

@@ -0,0 +1,22 @@
1
+from django.utils.deprecation import MiddlewareMixin
2
+from .pos import PosSys
3
+from .storefront import StoreFront
4
+
5
+class PosMiddleware(MiddlewareMixin):
6
+    def process_request(self, request):
7
+        if not hasattr(request, "user"):
8
+            raise ImproperlyConfigured(
9
+                "The Django POS middleware requires auth middleware")
10
+        user = request.user
11
+        if user.is_authenticated:
12
+            if not hasattr(request, 'pos') or request.pos is None:
13
+                pos = PosSys.restoreStore(user)
14
+                request.pos = pos
15
+        else:
16
+            request.pos = None
17
+
18
+        cstr  = request.GET.get('cstr', None)
19
+        if cstr:
20
+            request.storeFront = StoreFront(int(cstr))
21
+        else:
22
+            request.storeFront = None

+ 22 - 0
app/pos/migrations/0001_initial.py

@@ -0,0 +1,22 @@
1
+# Generated by Django 3.2.13 on 2022-05-14 08:48
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    initial = True
9
+
10
+    dependencies = [
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='MenuItem',
16
+            fields=[
17
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18
+                ('name', models.CharField(max_length=100)),
19
+                ('tagline', models.TextField()),
20
+            ],
21
+        ),
22
+    ]

+ 31 - 0
app/pos/migrations/0002_setting_store.py

@@ -0,0 +1,31 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 06:15
2
+
3
+import django.contrib.postgres.fields.hstore
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+
7
+from django.contrib.postgres.operations import HStoreExtension
8
+
9
+class Migration(migrations.Migration):
10
+
11
+    dependencies = [
12
+        ('pos', '0001_initial'),
13
+    ]
14
+
15
+    operations = [
16
+        HStoreExtension(),
17
+        migrations.CreateModel(
18
+            name='Store',
19
+            fields=[
20
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21
+                ('name', models.CharField(max_length=100)),
22
+            ],
23
+        ),
24
+        migrations.CreateModel(
25
+            name='Setting',
26
+            fields=[
27
+                ('store', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, serialize=False, to='pos.store')),
28
+                ('data', django.contrib.postgres.fields.hstore.HStoreField()),
29
+            ],
30
+        ),
31
+    ]

+ 19 - 0
app/pos/migrations/0003_alter_setting_data.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 06:55
2
+
3
+import django.contrib.postgres.fields.hstore
4
+from django.db import migrations
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0002_setting_store'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AlterField(
15
+            model_name='setting',
16
+            name='data',
17
+            field=django.contrib.postgres.fields.hstore.HStoreField(blank=True),
18
+        ),
19
+    ]

+ 31 - 0
app/pos/migrations/0004_auto_20220517_1613.py

@@ -0,0 +1,31 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 09:13
2
+
3
+import django.contrib.postgres.fields
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        ('pos', '0003_alter_setting_data'),
12
+    ]
13
+
14
+    operations = [
15
+        migrations.AddField(
16
+            model_name='menuitem',
17
+            name='photos',
18
+            field=django.contrib.postgres.fields.ArrayField(base_field=models.FileField(upload_to='uploads/%Y/%m/%d/'), blank=True, null=True, size=8),
19
+        ),
20
+        migrations.AddField(
21
+            model_name='menuitem',
22
+            name='store',
23
+            field=models.ForeignKey(default=None, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
24
+            preserve_default=False,
25
+        ),
26
+        migrations.AddField(
27
+            model_name='store',
28
+            name='photos',
29
+            field=django.contrib.postgres.fields.ArrayField(base_field=models.FileField(upload_to='uploads/%Y/%m/%d/'), blank=True, null=True, size=8),
30
+        ),
31
+    ]

+ 38 - 0
app/pos/migrations/0005_auto_20220517_2027.py

@@ -0,0 +1,38 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 13:27
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+import taggit.managers
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        ('taggit', '0005_auto_20220424_2025'),
12
+        ('pos', '0004_auto_20220517_1613'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.RemoveField(
17
+            model_name='menuitem',
18
+            name='photos',
19
+        ),
20
+        migrations.CreateModel(
21
+            name='StoreFile',
22
+            fields=[
23
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
24
+                ('storeFile', models.FileField(upload_to='uploads/%Y/%m/%d/')),
25
+                ('store', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.store')),
26
+                ('tags', taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
27
+            ],
28
+        ),
29
+        migrations.CreateModel(
30
+            name='MenuFile',
31
+            fields=[
32
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
33
+                ('menuFile', models.FileField(upload_to='uploads/%Y/%m/%d/')),
34
+                ('store', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.store')),
35
+                ('tags', taggit.managers.TaggableManager(help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
36
+            ],
37
+        ),
38
+    ]

+ 17 - 0
app/pos/migrations/0006_remove_store_photos.py

@@ -0,0 +1,17 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 13:28
2
+
3
+from django.db import migrations
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0005_auto_20220517_2027'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.RemoveField(
14
+            model_name='store',
15
+            name='photos',
16
+        ),
17
+    ]

+ 25 - 0
app/pos/migrations/0007_auto_20220517_2038.py

@@ -0,0 +1,25 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 13:38
2
+
3
+from django.db import migrations, models
4
+import django.utils.timezone
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0006_remove_store_photos'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='menuitem',
16
+            name='created_at',
17
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
18
+            preserve_default=False,
19
+        ),
20
+        migrations.AddField(
21
+            model_name='menuitem',
22
+            name='updated_at',
23
+            field=models.DateTimeField(auto_now=True),
24
+        ),
25
+    ]

+ 58 - 0
app/pos/migrations/0008_auto_20220517_2040.py

@@ -0,0 +1,58 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 13:40
2
+
3
+from django.db import migrations, models
4
+import django.utils.timezone
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0007_auto_20220517_2038'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='menufile',
16
+            name='created_at',
17
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
18
+            preserve_default=False,
19
+        ),
20
+        migrations.AddField(
21
+            model_name='menufile',
22
+            name='updated_at',
23
+            field=models.DateTimeField(auto_now=True),
24
+        ),
25
+        migrations.AddField(
26
+            model_name='setting',
27
+            name='created_at',
28
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
29
+            preserve_default=False,
30
+        ),
31
+        migrations.AddField(
32
+            model_name='setting',
33
+            name='updated_at',
34
+            field=models.DateTimeField(auto_now=True),
35
+        ),
36
+        migrations.AddField(
37
+            model_name='store',
38
+            name='created_at',
39
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
40
+            preserve_default=False,
41
+        ),
42
+        migrations.AddField(
43
+            model_name='store',
44
+            name='updated_at',
45
+            field=models.DateTimeField(auto_now=True),
46
+        ),
47
+        migrations.AddField(
48
+            model_name='storefile',
49
+            name='created_at',
50
+            field=models.DateTimeField(auto_now_add=True, default=django.utils.timezone.now),
51
+            preserve_default=False,
52
+        ),
53
+        migrations.AddField(
54
+            model_name='storefile',
55
+            name='updated_at',
56
+            field=models.DateTimeField(auto_now=True),
57
+        ),
58
+    ]

+ 55 - 0
app/pos/migrations/0009_bookingtable_order_table.py

@@ -0,0 +1,55 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 15:57
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0008_auto_20220517_2040'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='Table',
16
+            fields=[
17
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18
+                ('created_at', models.DateTimeField(auto_now_add=True)),
19
+                ('updated_at', models.DateTimeField(auto_now=True)),
20
+                ('nSeats', models.IntegerField(default=1)),
21
+                ('occupy', models.BooleanField(default=False)),
22
+                ('store', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.store')),
23
+            ],
24
+            options={
25
+                'abstract': False,
26
+            },
27
+        ),
28
+        migrations.CreateModel(
29
+            name='Order',
30
+            fields=[
31
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
32
+                ('created_at', models.DateTimeField(auto_now_add=True)),
33
+                ('updated_at', models.DateTimeField(auto_now=True)),
34
+                ('items', models.ManyToManyField(to='pos.MenuItem')),
35
+                ('table', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='pos.table')),
36
+            ],
37
+            options={
38
+                'abstract': False,
39
+            },
40
+        ),
41
+        migrations.CreateModel(
42
+            name='BookingTable',
43
+            fields=[
44
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
45
+                ('created_at', models.DateTimeField(auto_now_add=True)),
46
+                ('updated_at', models.DateTimeField(auto_now=True)),
47
+                ('onDate', models.DateTimeField()),
48
+                ('note', models.TextField(blank=True, null=True)),
49
+                ('table', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.table')),
50
+            ],
51
+            options={
52
+                'abstract': False,
53
+            },
54
+        ),
55
+    ]

+ 18 - 0
app/pos/migrations/0010_table_code.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 16:02
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0009_bookingtable_order_table'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='table',
15
+            name='code',
16
+            field=models.CharField(default='N\\A', max_length=100),
17
+        ),
18
+    ]

+ 32 - 0
app/pos/migrations/0011_auto_20220517_2307.py

@@ -0,0 +1,32 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 16:07
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0010_table_code'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.RemoveField(
15
+            model_name='order',
16
+            name='items',
17
+        ),
18
+        migrations.CreateModel(
19
+            name='OrderItem',
20
+            fields=[
21
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
22
+                ('created_at', models.DateTimeField(auto_now_add=True)),
23
+                ('updated_at', models.DateTimeField(auto_now=True)),
24
+                ('qty', models.IntegerField(default=1)),
25
+                ('item', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.menuitem')),
26
+                ('order', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.order')),
27
+            ],
28
+            options={
29
+                'abstract': False,
30
+            },
31
+        ),
32
+    ]

+ 18 - 0
app/pos/migrations/0012_alter_menuitem_tagline.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-05-17 16:12
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0011_auto_20220517_2307'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AlterField(
14
+            model_name='menuitem',
15
+            name='tagline',
16
+            field=models.TextField(blank=True, null=True),
17
+        ),
18
+    ]

+ 103 - 0
app/pos/migrations/0013_auto_20220518_1430.py

@@ -0,0 +1,103 @@
1
+# Generated by Django 3.2.13 on 2022-05-18 07:30
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0012_alter_menuitem_tagline'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='bookingtable',
15
+            name='inProcess',
16
+            field=models.CharField(blank=True, max_length=100, null=True),
17
+        ),
18
+        migrations.AddField(
19
+            model_name='bookingtable',
20
+            name='status',
21
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
22
+        ),
23
+        migrations.AddField(
24
+            model_name='menufile',
25
+            name='inProcess',
26
+            field=models.CharField(blank=True, max_length=100, null=True),
27
+        ),
28
+        migrations.AddField(
29
+            model_name='menufile',
30
+            name='status',
31
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
32
+        ),
33
+        migrations.AddField(
34
+            model_name='menuitem',
35
+            name='inProcess',
36
+            field=models.CharField(blank=True, max_length=100, null=True),
37
+        ),
38
+        migrations.AddField(
39
+            model_name='menuitem',
40
+            name='status',
41
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
42
+        ),
43
+        migrations.AddField(
44
+            model_name='order',
45
+            name='inProcess',
46
+            field=models.CharField(blank=True, max_length=100, null=True),
47
+        ),
48
+        migrations.AddField(
49
+            model_name='order',
50
+            name='status',
51
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
52
+        ),
53
+        migrations.AddField(
54
+            model_name='orderitem',
55
+            name='inProcess',
56
+            field=models.CharField(blank=True, max_length=100, null=True),
57
+        ),
58
+        migrations.AddField(
59
+            model_name='orderitem',
60
+            name='status',
61
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
62
+        ),
63
+        migrations.AddField(
64
+            model_name='setting',
65
+            name='inProcess',
66
+            field=models.CharField(blank=True, max_length=100, null=True),
67
+        ),
68
+        migrations.AddField(
69
+            model_name='setting',
70
+            name='status',
71
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
72
+        ),
73
+        migrations.AddField(
74
+            model_name='store',
75
+            name='inProcess',
76
+            field=models.CharField(blank=True, max_length=100, null=True),
77
+        ),
78
+        migrations.AddField(
79
+            model_name='store',
80
+            name='status',
81
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
82
+        ),
83
+        migrations.AddField(
84
+            model_name='storefile',
85
+            name='inProcess',
86
+            field=models.CharField(blank=True, max_length=100, null=True),
87
+        ),
88
+        migrations.AddField(
89
+            model_name='storefile',
90
+            name='status',
91
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
92
+        ),
93
+        migrations.AddField(
94
+            model_name='table',
95
+            name='inProcess',
96
+            field=models.CharField(blank=True, max_length=100, null=True),
97
+        ),
98
+        migrations.AddField(
99
+            model_name='table',
100
+            name='status',
101
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100),
102
+        ),
103
+    ]

+ 18 - 0
app/pos/migrations/0014_order_note.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-05-19 14:23
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0013_auto_20220518_1430'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='order',
15
+            name='note',
16
+            field=models.TextField(blank=True, null=True),
17
+        ),
18
+    ]

+ 32 - 0
app/pos/migrations/0015_ingredient.py

@@ -0,0 +1,32 @@
1
+# Generated by Django 3.2.13 on 2022-05-19 14:30
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0014_order_note'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.CreateModel(
15
+            name='Ingredient',
16
+            fields=[
17
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
18
+                ('created_at', models.DateTimeField(auto_now_add=True)),
19
+                ('updated_at', models.DateTimeField(auto_now=True)),
20
+                ('inProcess', models.CharField(blank=True, max_length=100, null=True)),
21
+                ('status', models.CharField(choices=[('process', 'Process'), ('fn', 'Finished')], default='process', max_length=100)),
22
+                ('name', models.CharField(max_length=200)),
23
+                ('qty', models.DecimalField(decimal_places=2, max_digits=5)),
24
+                ('unit', models.CharField(max_length=10)),
25
+                ('comment', models.TextField(blank=True, null=True)),
26
+                ('menu', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.menuitem')),
27
+            ],
28
+            options={
29
+                'abstract': False,
30
+            },
31
+        ),
32
+    ]

+ 26 - 0
app/pos/migrations/0016_profile.py

@@ -0,0 +1,26 @@
1
+# Generated by Django 3.2.13 on 2022-05-19 14:40
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12
+        ('pos', '0015_ingredient'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.CreateModel(
17
+            name='Profile',
18
+            fields=[
19
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
+                ('location', models.CharField(blank=True, max_length=30)),
21
+                ('birthdate', models.DateField(blank=True, null=True)),
22
+                ('role', models.PositiveSmallIntegerField(blank=True, choices=[(1, 'Store Owner'), (2, 'Chef'), (3, 'Employee')], null=True)),
23
+                ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
24
+            ],
25
+        ),
26
+    ]

+ 66 - 0
app/pos/migrations/0017_auto_20220519_2146.py

@@ -0,0 +1,66 @@
1
+# Generated by Django 3.2.13 on 2022-05-19 14:46
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12
+        ('pos', '0016_profile'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.AddField(
17
+            model_name='bookingtable',
18
+            name='owner',
19
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
20
+        ),
21
+        migrations.AddField(
22
+            model_name='ingredient',
23
+            name='owner',
24
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
25
+        ),
26
+        migrations.AddField(
27
+            model_name='menufile',
28
+            name='owner',
29
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
30
+        ),
31
+        migrations.AddField(
32
+            model_name='menuitem',
33
+            name='owner',
34
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
35
+        ),
36
+        migrations.AddField(
37
+            model_name='order',
38
+            name='owner',
39
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
40
+        ),
41
+        migrations.AddField(
42
+            model_name='orderitem',
43
+            name='owner',
44
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
45
+        ),
46
+        migrations.AddField(
47
+            model_name='setting',
48
+            name='owner',
49
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
50
+        ),
51
+        migrations.AddField(
52
+            model_name='store',
53
+            name='owner',
54
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
55
+        ),
56
+        migrations.AddField(
57
+            model_name='storefile',
58
+            name='owner',
59
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
60
+        ),
61
+        migrations.AddField(
62
+            model_name='table',
63
+            name='owner',
64
+            field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
65
+        ),
66
+    ]

+ 68 - 0
app/pos/migrations/0018_auto_20220520_2029.py

@@ -0,0 +1,68 @@
1
+# Generated by Django 3.2.13 on 2022-05-20 13:29
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0017_auto_20220519_2146'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='orderitem',
15
+            name='note',
16
+            field=models.TextField(blank=True, null=True),
17
+        ),
18
+        migrations.AlterField(
19
+            model_name='bookingtable',
20
+            name='status',
21
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
22
+        ),
23
+        migrations.AlterField(
24
+            model_name='ingredient',
25
+            name='status',
26
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
27
+        ),
28
+        migrations.AlterField(
29
+            model_name='menufile',
30
+            name='status',
31
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
32
+        ),
33
+        migrations.AlterField(
34
+            model_name='menuitem',
35
+            name='status',
36
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
37
+        ),
38
+        migrations.AlterField(
39
+            model_name='order',
40
+            name='status',
41
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
42
+        ),
43
+        migrations.AlterField(
44
+            model_name='orderitem',
45
+            name='status',
46
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
47
+        ),
48
+        migrations.AlterField(
49
+            model_name='setting',
50
+            name='status',
51
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
52
+        ),
53
+        migrations.AlterField(
54
+            model_name='store',
55
+            name='status',
56
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
57
+        ),
58
+        migrations.AlterField(
59
+            model_name='storefile',
60
+            name='status',
61
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
62
+        ),
63
+        migrations.AlterField(
64
+            model_name='table',
65
+            name='status',
66
+            field=models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100),
67
+        ),
68
+    ]

+ 39 - 0
app/pos/migrations/0019_uimenu.py

@@ -0,0 +1,39 @@
1
+# Generated by Django 3.2.13 on 2022-05-21 03:32
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+import mptt.fields
7
+
8
+
9
+class Migration(migrations.Migration):
10
+
11
+    dependencies = [
12
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13
+        ('pos', '0018_auto_20220520_2029'),
14
+    ]
15
+
16
+    operations = [
17
+        migrations.CreateModel(
18
+            name='UIMenu',
19
+            fields=[
20
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21
+                ('created_at', models.DateTimeField(auto_now_add=True)),
22
+                ('updated_at', models.DateTimeField(auto_now=True)),
23
+                ('inProcess', models.CharField(blank=True, max_length=100, null=True)),
24
+                ('status', models.CharField(choices=[('process', 'Process'), ('fn', 'Finished'), ('purchase', 'Purchase')], default='process', max_length=100)),
25
+                ('name', models.CharField(max_length=200)),
26
+                ('group', models.CharField(max_length=200)),
27
+                ('url', models.URLField()),
28
+                ('lft', models.PositiveIntegerField(editable=False)),
29
+                ('rght', models.PositiveIntegerField(editable=False)),
30
+                ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
31
+                ('level', models.PositiveIntegerField(editable=False)),
32
+                ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
33
+                ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='pos.uimenu')),
34
+            ],
35
+            options={
36
+                'abstract': False,
37
+            },
38
+        ),
39
+    ]

+ 22 - 0
app/pos/migrations/0020_setting_note.py

@@ -0,0 +1,22 @@
1
+# Generated by Django 3.2.13 on 2022-05-21 04:43
2
+
3
+from django.db import migrations, models
4
+from django.contrib.postgres.operations import HStoreExtension, UnaccentExtension
5
+
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        ('pos', '0019_uimenu'),
12
+    ]
13
+
14
+    operations = [
15
+        HStoreExtension(),
16
+        UnaccentExtension(),
17
+        migrations.AddField(
18
+            model_name='setting',
19
+            name='note',
20
+            field=models.CharField(blank=True, max_length=200, null=True),
21
+        ),
22
+    ]

+ 19 - 0
app/pos/migrations/0021_alter_setting_data.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-21 04:45
2
+
3
+import django.contrib.postgres.fields.hstore
4
+from django.db import migrations
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0020_setting_note'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AlterField(
15
+            model_name='setting',
16
+            name='data',
17
+            field=django.contrib.postgres.fields.hstore.HStoreField(blank=True, null=True),
18
+        ),
19
+    ]

+ 18 - 0
app/pos/migrations/0022_alter_uimenu_url.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-05-21 05:21
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0021_alter_setting_data'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AlterField(
14
+            model_name='uimenu',
15
+            name='url',
16
+            field=models.CharField(max_length=200),
17
+        ),
18
+    ]

+ 18 - 0
app/pos/migrations/0023_alter_store_name.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-05-21 05:27
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0022_alter_uimenu_url'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AlterField(
14
+            model_name='store',
15
+            name='name',
16
+            field=models.CharField(default='Unititled', max_length=100),
17
+        ),
18
+    ]

+ 19 - 0
app/pos/migrations/0024_uimenu_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-21 07:33
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0023_alter_store_name'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='uimenu',
16
+            name='store',
17
+            field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
18
+        ),
19
+    ]

+ 18 - 0
app/pos/migrations/0025_uimenu_icon.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-05-22 16:34
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0024_uimenu_store'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='uimenu',
15
+            name='icon',
16
+            field=models.CharField(blank=True, default='file', max_length=100, null=True),
17
+        ),
18
+    ]

+ 19 - 0
app/pos/migrations/0026_order_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-23 05:24
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0025_uimenu_icon'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='order',
16
+            name='store',
17
+            field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pos.store'),
18
+        ),
19
+    ]

+ 19 - 0
app/pos/migrations/0027_orderitem_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-24 04:51
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0026_order_store'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='orderitem',
16
+            name='store',
17
+            field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pos.store'),
18
+        ),
19
+    ]

+ 28 - 0
app/pos/migrations/0028_auto_20220529_1350.py

@@ -0,0 +1,28 @@
1
+# Generated by Django 3.2.13 on 2022-05-29 06:50
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0027_orderitem_store'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='store',
15
+            name='address',
16
+            field=models.TextField(blank=True, null=True),
17
+        ),
18
+        migrations.AddField(
19
+            model_name='store',
20
+            name='province',
21
+            field=models.CharField(blank=True, max_length=100, null=True),
22
+        ),
23
+        migrations.AddField(
24
+            model_name='store',
25
+            name='storeType',
26
+            field=models.CharField(blank=True, max_length=100, null=True),
27
+        ),
28
+    ]

+ 40 - 0
app/pos/migrations/0029_auto_20220530_1225.py

@@ -0,0 +1,40 @@
1
+# Generated by Django 3.2.13 on 2022-05-30 05:25
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+import taggit.managers
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        ('taggit', '0005_auto_20220424_2025'),
12
+        ('pos', '0028_auto_20220529_1350'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.RemoveField(
17
+            model_name='menufile',
18
+            name='store',
19
+        ),
20
+        migrations.AddField(
21
+            model_name='menufile',
22
+            name='menuItem',
23
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.menuitem'),
24
+        ),
25
+        migrations.AlterField(
26
+            model_name='menufile',
27
+            name='tags',
28
+            field=taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
29
+        ),
30
+        migrations.AlterField(
31
+            model_name='store',
32
+            name='storeType',
33
+            field=models.CharField(blank=True, max_length=100, null=True, verbose_name='Store Type'),
34
+        ),
35
+        migrations.AlterField(
36
+            model_name='storefile',
37
+            name='tags',
38
+            field=taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
39
+        ),
40
+    ]

+ 19 - 0
app/pos/migrations/0030_bookingtable_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-30 07:10
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0029_auto_20220530_1225'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='bookingtable',
16
+            name='store',
17
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
18
+        ),
19
+    ]

+ 23 - 0
app/pos/migrations/0031_auto_20220530_1417.py

@@ -0,0 +1,23 @@
1
+# Generated by Django 3.2.13 on 2022-05-30 07:17
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0030_bookingtable_store'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='bookingtable',
15
+            name='onTime',
16
+            field=models.TimeField(null=True),
17
+        ),
18
+        migrations.AlterField(
19
+            model_name='bookingtable',
20
+            name='onDate',
21
+            field=models.DateField(null=True),
22
+        ),
23
+    ]

+ 135 - 0
app/pos/migrations/0032_auto_20220530_1510.py

@@ -0,0 +1,135 @@
1
+# Generated by Django 3.2.13 on 2022-05-30 08:10
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+import djrichtextfield.models
7
+import mptt.fields
8
+
9
+
10
+class Migration(migrations.Migration):
11
+
12
+    dependencies = [
13
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
14
+        ('pos', '0031_auto_20220530_1417'),
15
+    ]
16
+
17
+    operations = [
18
+        migrations.RemoveField(
19
+            model_name='bookingtable',
20
+            name='inProcess',
21
+        ),
22
+        migrations.RemoveField(
23
+            model_name='bookingtable',
24
+            name='status',
25
+        ),
26
+        migrations.RemoveField(
27
+            model_name='ingredient',
28
+            name='inProcess',
29
+        ),
30
+        migrations.RemoveField(
31
+            model_name='ingredient',
32
+            name='status',
33
+        ),
34
+        migrations.RemoveField(
35
+            model_name='menufile',
36
+            name='inProcess',
37
+        ),
38
+        migrations.RemoveField(
39
+            model_name='menufile',
40
+            name='status',
41
+        ),
42
+        migrations.RemoveField(
43
+            model_name='menuitem',
44
+            name='inProcess',
45
+        ),
46
+        migrations.RemoveField(
47
+            model_name='menuitem',
48
+            name='status',
49
+        ),
50
+        migrations.RemoveField(
51
+            model_name='order',
52
+            name='inProcess',
53
+        ),
54
+        migrations.RemoveField(
55
+            model_name='order',
56
+            name='status',
57
+        ),
58
+        migrations.RemoveField(
59
+            model_name='orderitem',
60
+            name='inProcess',
61
+        ),
62
+        migrations.RemoveField(
63
+            model_name='orderitem',
64
+            name='status',
65
+        ),
66
+        migrations.RemoveField(
67
+            model_name='setting',
68
+            name='inProcess',
69
+        ),
70
+        migrations.RemoveField(
71
+            model_name='setting',
72
+            name='status',
73
+        ),
74
+        migrations.RemoveField(
75
+            model_name='store',
76
+            name='inProcess',
77
+        ),
78
+        migrations.RemoveField(
79
+            model_name='store',
80
+            name='status',
81
+        ),
82
+        migrations.RemoveField(
83
+            model_name='storefile',
84
+            name='inProcess',
85
+        ),
86
+        migrations.RemoveField(
87
+            model_name='storefile',
88
+            name='status',
89
+        ),
90
+        migrations.RemoveField(
91
+            model_name='table',
92
+            name='inProcess',
93
+        ),
94
+        migrations.RemoveField(
95
+            model_name='table',
96
+            name='status',
97
+        ),
98
+        migrations.RemoveField(
99
+            model_name='uimenu',
100
+            name='inProcess',
101
+        ),
102
+        migrations.RemoveField(
103
+            model_name='uimenu',
104
+            name='status',
105
+        ),
106
+        migrations.CreateModel(
107
+            name='PostCategory',
108
+            fields=[
109
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
110
+                ('name', models.CharField(max_length=200)),
111
+                ('lft', models.PositiveIntegerField(editable=False)),
112
+                ('rght', models.PositiveIntegerField(editable=False)),
113
+                ('tree_id', models.PositiveIntegerField(db_index=True, editable=False)),
114
+                ('level', models.PositiveIntegerField(editable=False)),
115
+                ('parent', mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='children', to='pos.postcategory')),
116
+            ],
117
+            options={
118
+                'abstract': False,
119
+            },
120
+        ),
121
+        migrations.CreateModel(
122
+            name='Post',
123
+            fields=[
124
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
125
+                ('created_at', models.DateTimeField(auto_now_add=True)),
126
+                ('updated_at', models.DateTimeField(auto_now=True)),
127
+                ('title', models.CharField(max_length=200)),
128
+                ('content', djrichtextfield.models.RichTextField()),
129
+                ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
130
+            ],
131
+            options={
132
+                'abstract': False,
133
+            },
134
+        ),
135
+    ]

+ 19 - 0
app/pos/migrations/0033_post_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-30 08:29
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0032_auto_20220530_1510'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='post',
16
+            name='store',
17
+            field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
18
+        ),
19
+    ]

+ 31 - 0
app/pos/migrations/0034_auto_20220531_2134.py

@@ -0,0 +1,31 @@
1
+# Generated by Django 3.2.13 on 2022-05-31 14:34
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+import djrichtextfield.models
6
+import mptt.fields
7
+
8
+
9
+class Migration(migrations.Migration):
10
+
11
+    dependencies = [
12
+        ('pos', '0033_post_store'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.AddField(
17
+            model_name='post',
18
+            name='category',
19
+            field=mptt.fields.TreeForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, to='pos.postcategory'),
20
+        ),
21
+        migrations.AddField(
22
+            model_name='post',
23
+            name='featureImage',
24
+            field=models.ImageField(blank=True, height_field=800, null=True, upload_to='uploads/%Y/%m/%d/', width_field=450),
25
+        ),
26
+        migrations.AlterField(
27
+            model_name='post',
28
+            name='content',
29
+            field=djrichtextfield.models.RichTextField(blank=True),
30
+        ),
31
+    ]

+ 23 - 0
app/pos/migrations/0035_auto_20220531_2151.py

@@ -0,0 +1,23 @@
1
+# Generated by Django 3.2.13 on 2022-05-31 14:51
2
+
3
+from django.db import migrations
4
+import mptt.fields
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0034_auto_20220531_2134'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.RemoveField(
15
+            model_name='post',
16
+            name='category',
17
+        ),
18
+        migrations.AddField(
19
+            model_name='post',
20
+            name='category',
21
+            field=mptt.fields.TreeManyToManyField(blank=True, null=True, to='pos.PostCategory'),
22
+        ),
23
+    ]

+ 18 - 0
app/pos/migrations/0036_alter_post_featureimage.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-05-31 15:01
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0035_auto_20220531_2151'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AlterField(
14
+            model_name='post',
15
+            name='featureImage',
16
+            field=models.ImageField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
17
+        ),
18
+    ]

+ 19 - 0
app/pos/migrations/0037_post_photos.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-05-31 15:06
2
+
3
+import django.contrib.postgres.fields
4
+from django.db import migrations, models
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0036_alter_post_featureimage'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='post',
16
+            name='photos',
17
+            field=django.contrib.postgres.fields.ArrayField(base_field=models.ImageField(upload_to='uploads/%Y/%m/%d/'), blank=True, null=True, size=None),
18
+        ),
19
+    ]

+ 37 - 0
app/pos/migrations/0038_auto_20220531_2208.py

@@ -0,0 +1,37 @@
1
+# Generated by Django 3.2.13 on 2022-05-31 15:08
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+import taggit.managers
7
+
8
+
9
+class Migration(migrations.Migration):
10
+
11
+    dependencies = [
12
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13
+        ('taggit', '0005_auto_20220424_2025'),
14
+        ('pos', '0037_post_photos'),
15
+    ]
16
+
17
+    operations = [
18
+        migrations.RemoveField(
19
+            model_name='post',
20
+            name='photos',
21
+        ),
22
+        migrations.CreateModel(
23
+            name='PostFile',
24
+            fields=[
25
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
26
+                ('created_at', models.DateTimeField(auto_now_add=True)),
27
+                ('updated_at', models.DateTimeField(auto_now=True)),
28
+                ('file', models.FileField(upload_to='uploads/%Y/%m/%d/')),
29
+                ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
30
+                ('post', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='pos.post')),
31
+                ('tags', taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags')),
32
+            ],
33
+            options={
34
+                'abstract': False,
35
+            },
36
+        ),
37
+    ]

+ 20 - 0
app/pos/migrations/0039_post_tags.py

@@ -0,0 +1,20 @@
1
+# Generated by Django 3.2.13 on 2022-06-01 07:23
2
+
3
+from django.db import migrations
4
+import taggit.managers
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('taggit', '0005_auto_20220424_2025'),
11
+        ('pos', '0038_auto_20220531_2208'),
12
+    ]
13
+
14
+    operations = [
15
+        migrations.AddField(
16
+            model_name='post',
17
+            name='tags',
18
+            field=taggit.managers.TaggableManager(blank=True, help_text='A comma-separated list of tags.', through='taggit.TaggedItem', to='taggit.Tag', verbose_name='Tags'),
19
+        ),
20
+    ]

+ 18 - 0
app/pos/migrations/0040_post_description.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-01 07:36
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0039_post_tags'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='post',
15
+            name='description',
16
+            field=models.TextField(blank=True, null=True),
17
+        ),
18
+    ]

+ 32 - 0
app/pos/migrations/0041_customer.py

@@ -0,0 +1,32 @@
1
+# Generated by Django 3.2.13 on 2022-06-01 07:41
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+
7
+
8
+class Migration(migrations.Migration):
9
+
10
+    dependencies = [
11
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
12
+        ('pos', '0040_post_description'),
13
+    ]
14
+
15
+    operations = [
16
+        migrations.CreateModel(
17
+            name='Customer',
18
+            fields=[
19
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
20
+                ('created_at', models.DateTimeField(auto_now_add=True)),
21
+                ('updated_at', models.DateTimeField(auto_now=True)),
22
+                ('fullName', models.CharField(max_length=200)),
23
+                ('email', models.EmailField(blank=True, max_length=254, null=True)),
24
+                ('lineId', models.CharField(blank=True, max_length=100, null=True)),
25
+                ('gender', models.CharField(choices=[('na', 'N/A'), ('lgbt', 'LGBT'), ('male', 'Male'), ('female', 'Female')], default='na', max_length=40)),
26
+                ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
27
+            ],
28
+            options={
29
+                'abstract': False,
30
+            },
31
+        ),
32
+    ]

+ 19 - 0
app/pos/migrations/0042_customer_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-06-01 08:19
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0041_customer'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='customer',
16
+            name='store',
17
+            field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
18
+        ),
19
+    ]

+ 32 - 0
app/pos/migrations/0043_code.py

@@ -0,0 +1,32 @@
1
+# Generated by Django 3.2.13 on 2022-06-02 14:02
2
+
3
+from django.conf import settings
4
+from django.db import migrations, models
5
+import django.db.models.deletion
6
+import django_editorjs_fields.fields
7
+
8
+
9
+class Migration(migrations.Migration):
10
+
11
+    dependencies = [
12
+        migrations.swappable_dependency(settings.AUTH_USER_MODEL),
13
+        ('pos', '0042_customer_store'),
14
+    ]
15
+
16
+    operations = [
17
+        migrations.CreateModel(
18
+            name='Code',
19
+            fields=[
20
+                ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21
+                ('created_at', models.DateTimeField(auto_now_add=True)),
22
+                ('updated_at', models.DateTimeField(auto_now=True)),
23
+                ('body_default', models.TextField()),
24
+                ('body_editorjs', django_editorjs_fields.fields.EditorJsJSONField()),
25
+                ('body_editorjs_text', django_editorjs_fields.fields.EditorJsTextField()),
26
+                ('owner', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
27
+            ],
28
+            options={
29
+                'abstract': False,
30
+            },
31
+        ),
32
+    ]

+ 24 - 0
app/pos/migrations/0044_auto_20220603_1058.py

@@ -0,0 +1,24 @@
1
+# Generated by Django 3.2.13 on 2022-06-03 03:58
2
+
3
+from django.db import migrations
4
+import filebrowser.fields
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0043_code'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='code',
16
+            name='document',
17
+            field=filebrowser.fields.FileBrowseField(blank=True, max_length=200, verbose_name='PDF'),
18
+        ),
19
+        migrations.AddField(
20
+            model_name='code',
21
+            name='image',
22
+            field=filebrowser.fields.FileBrowseField(blank=True, max_length=200, verbose_name='Image'),
23
+        ),
24
+    ]

+ 18 - 0
app/pos/migrations/0045_code_code.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-03 04:35
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0044_auto_20220603_1058'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='code',
15
+            name='code',
16
+            field=models.TextField(blank=True),
17
+        ),
18
+    ]

+ 48 - 0
app/pos/migrations/0046_auto_20220603_1258.py

@@ -0,0 +1,48 @@
1
+# Generated by Django 3.2.13 on 2022-06-03 05:58
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0045_code_code'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.RenameField(
14
+            model_name='code',
15
+            old_name='code',
16
+            new_name='cssCode',
17
+        ),
18
+        migrations.RemoveField(
19
+            model_name='code',
20
+            name='body_default',
21
+        ),
22
+        migrations.RemoveField(
23
+            model_name='code',
24
+            name='body_editorjs',
25
+        ),
26
+        migrations.RemoveField(
27
+            model_name='code',
28
+            name='body_editorjs_text',
29
+        ),
30
+        migrations.RemoveField(
31
+            model_name='code',
32
+            name='document',
33
+        ),
34
+        migrations.RemoveField(
35
+            model_name='code',
36
+            name='image',
37
+        ),
38
+        migrations.AddField(
39
+            model_name='code',
40
+            name='jsCode',
41
+            field=models.TextField(blank=True),
42
+        ),
43
+        migrations.AddField(
44
+            model_name='code',
45
+            name='pluginCode',
46
+            field=models.TextField(blank=True),
47
+        ),
48
+    ]

+ 19 - 0
app/pos/migrations/0047_code_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-06-03 06:07
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0046_auto_20220603_1258'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='code',
16
+            name='store',
17
+            field=models.ForeignKey(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
18
+        ),
19
+    ]

+ 19 - 0
app/pos/migrations/0048_alter_code_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-06-03 06:15
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0047_code_store'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AlterField(
15
+            model_name='code',
16
+            name='store',
17
+            field=models.OneToOneField(default=None, null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
18
+        ),
19
+    ]

+ 18 - 0
app/pos/migrations/0049_uimenu_norder.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-03 08:01
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0048_alter_code_store'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='uimenu',
15
+            name='nOrder',
16
+            field=models.IntegerField(default=1),
17
+        ),
18
+    ]

+ 19 - 0
app/pos/migrations/0050_profile_store.py

@@ -0,0 +1,19 @@
1
+# Generated by Django 3.2.13 on 2022-06-03 13:47
2
+
3
+from django.db import migrations, models
4
+import django.db.models.deletion
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0049_uimenu_norder'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='profile',
16
+            name='store',
17
+            field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to='pos.store'),
18
+        ),
19
+    ]

+ 18 - 0
app/pos/migrations/0051_menuitem_qrcode.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-05 17:25
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0050_profile_store'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='menuitem',
15
+            name='qrCode',
16
+            field=models.BinaryField(blank=True, null=True),
17
+        ),
18
+    ]

+ 18 - 0
app/pos/migrations/0052_alter_menuitem_qrcode.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-05 17:59
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0051_menuitem_qrcode'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AlterField(
14
+            model_name='menuitem',
15
+            name='qrCode',
16
+            field=models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
17
+        ),
18
+    ]

+ 23 - 0
app/pos/migrations/0053_auto_20220606_1058.py

@@ -0,0 +1,23 @@
1
+# Generated by Django 3.2.13 on 2022-06-06 03:58
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0052_alter_menuitem_qrcode'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='order',
15
+            name='qrCode',
16
+            field=models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
17
+        ),
18
+        migrations.AddField(
19
+            model_name='store',
20
+            name='qrCode',
21
+            field=models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
22
+        ),
23
+    ]

+ 23 - 0
app/pos/migrations/0054_auto_20220606_1336.py

@@ -0,0 +1,23 @@
1
+# Generated by Django 3.2.13 on 2022-06-06 06:36
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0053_auto_20220606_1058'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='bookingtable',
15
+            name='qrCode',
16
+            field=models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
17
+        ),
18
+        migrations.AddField(
19
+            model_name='table',
20
+            name='qrCode',
21
+            field=models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
22
+        ),
23
+    ]

+ 18 - 0
app/pos/migrations/0055_customer_qrcode.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-06 06:41
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0054_auto_20220606_1336'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='customer',
15
+            name='qrCode',
16
+            field=models.FileField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
17
+        ),
18
+    ]

+ 24 - 0
app/pos/migrations/0056_auto_20220606_1348.py

@@ -0,0 +1,24 @@
1
+# Generated by Django 3.2.13 on 2022-06-06 06:48
2
+
3
+from django.db import migrations
4
+import django_google_maps.fields
5
+
6
+
7
+class Migration(migrations.Migration):
8
+
9
+    dependencies = [
10
+        ('pos', '0055_customer_qrcode'),
11
+    ]
12
+
13
+    operations = [
14
+        migrations.AddField(
15
+            model_name='store',
16
+            name='geolocation',
17
+            field=django_google_maps.fields.GeoLocationField(blank=True, max_length=100, null=True),
18
+        ),
19
+        migrations.AlterField(
20
+            model_name='store',
21
+            name='address',
22
+            field=django_google_maps.fields.AddressField(blank=True, max_length=100, null=True),
23
+        ),
24
+    ]

+ 18 - 0
app/pos/migrations/0057_store_addresstext.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-06 06:50
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0056_auto_20220606_1348'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='store',
15
+            name='addressText',
16
+            field=models.TextField(blank=True, null=True),
17
+        ),
18
+    ]

+ 18 - 0
app/pos/migrations/0058_post_relatemenus.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-11 13:18
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0057_store_addresstext'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='post',
15
+            name='relateMenus',
16
+            field=models.ManyToManyField(blank=True, null=True, to='pos.MenuItem'),
17
+        ),
18
+    ]

+ 18 - 0
app/pos/migrations/0059_menuitem_featureimage.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-11 16:17
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0058_post_relatemenus'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='menuitem',
15
+            name='featureImage',
16
+            field=models.ImageField(blank=True, null=True, upload_to='uploads/%Y/%m/%d/'),
17
+        ),
18
+    ]

+ 18 - 0
app/pos/migrations/0060_menuitem_description.py

@@ -0,0 +1,18 @@
1
+# Generated by Django 3.2.13 on 2022-06-12 05:51
2
+
3
+from django.db import migrations, models
4
+
5
+
6
+class Migration(migrations.Migration):
7
+
8
+    dependencies = [
9
+        ('pos', '0059_menuitem_featureimage'),
10
+    ]
11
+
12
+    operations = [
13
+        migrations.AddField(
14
+            model_name='menuitem',
15
+            name='description',
16
+            field=models.TextField(blank=True, null=True),
17
+        ),
18
+    ]

+ 0 - 0
app/pos/migrations/0061_store_logo.py


Некоторые файлы не были показаны из-за большого количества измененных файлов

tum/tmt_learning - Gogs: Simplico Git Service

Нет описания

Prach Pongpanich 6f337d0a21 install tailwind alpine daisyui лет назад: 3
..
dist 6f337d0a21 install tailwind alpine daisyui лет назад: 3
LICENSE 6f337d0a21 install tailwind alpine daisyui лет назад: 3
index.js 6f337d0a21 install tailwind alpine daisyui лет назад: 3
package.json 6f337d0a21 install tailwind alpine daisyui лет назад: 3
readme.markdown 6f337d0a21 install tailwind alpine daisyui лет назад: 3

readme.markdown

object-hash

Generate hashes from objects and values in node and the browser. Uses node.js crypto module for hashing. Supports SHA1 and many others (depending on the platform) as well as custom streams (e.g. CRC32).

NPM

Travis CI Coverage Status

  • Hash values of any type.
  • Supports a keys only option for grouping similar objects with different values.
var hash = require('object-hash');

hash({foo: 'bar'}) // => '67b69634f9880a282c14a0f0cb7ba20cf5d677e9'
hash([1, 2, 2.718, 3.14159]) // => '136b9b88375971dff9f1af09d7356e3e04281951'

Versioning Disclaimer

Starting with version 1.1.8 (released April 2017), new versions will consider the exact returned hash part of the API contract, i.e. changes that will affect hash values will be considered semver-major. Previous versions may violate that expectation.

For more information, see this discussion.

hash(value, options)

Generate a hash from any object or type. Defaults to sha1 with hex encoding.

  • algorithm hash algo to be used: 'sha1', 'md5', 'passthrough'. default: sha1
    • This supports the algorithms returned by crypto.getHashes(). Note that the default of SHA-1 is not considered secure, and a stronger algorithm should be used if a cryptographical hash is desired.
    • This also supports the passthrough algorith, which will return the information that would otherwise have been hashed.
  • excludeValues {true|false} hash object keys, values ignored. default: false
  • encoding hash encoding, supports 'buffer', 'hex', 'binary', 'base64'. default: hex
  • ignoreUnknown {true|*false} ignore unknown object types. default: false
  • replacer optional function that replaces values before hashing. default: accept all values
  • respectFunctionProperties {true|false} Whether properties on functions are considered when hashing. default: true
  • respectFunctionNames {true|false} consider name property of functions for hashing. default: true
  • respectType {true|false} Whether special type attributes (.prototype, .__proto__, .constructor) are hashed. default: true
  • unorderedArrays {true|false} Sort all arrays before hashing. Note that this affects all collections, i.e. including typed arrays, Sets, Maps, etc. default: false
  • unorderedSets {true|false} Sort Set and Map instances before hashing, i.e. make hash(new Set([1, 2])) == hash(new Set([2, 1])) return true. default: true
  • unorderedObjects {true|false} Sort objects before hashing, i.e. make hash({ x: 1, y: 2 }) === hash({ y: 2, x: 1 }). default: true
  • excludeKeys optional function for excluding specific key(s) from hashing, if true is returned then exclude from hash. default: include all keys

hash.sha1(value)

Hash using the sha1 algorithm.

Note that SHA-1 is not considered secure, and a stronger algorithm should be used if a cryptographical hash is desired.

Sugar method, equivalent to hash(value, {algorithm: 'sha1'})

hash.keys(value)

Hash object keys using the sha1 algorithm, values ignored.

Sugar method, equivalent to hash(value, {excludeValues: true})

hash.MD5(value)

Hash using the md5 algorithm.

Note that the MD5 algorithm is not considered secure, and a stronger algorithm should be used if a cryptographical hash is desired.

Sugar method, equivalent to hash(value, {algorithm: 'md5'})

hash.keysMD5(value)

Hash object keys using the md5 algorithm, values ignored.

Note that the MD5 algorithm is not considered secure, and a stronger algorithm should be used if a cryptographical hash is desired.

Sugar method, equivalent to hash(value, {algorithm: 'md5', excludeValues: true})

hash.writeToStream(value, [options,] stream)

Write the information that would otherwise have been hashed to a stream, e.g.:

hash.writeToStream({foo: 'bar', a: 42}, {respectType: false}, process.stdout)
// => e.g. 'object:a:number:42foo:string:bar'

Installation

node:

npm install object-hash

browser: /dist/object_hash.js

<script src="object_hash.js" type="text/javascript"></script>

<script>
  var hash = objectHash.sha1({foo:'bar'});

  console.log(hash); // e003c89cdf35cdf46d8239b4692436364b7259f9
</script>

Example usage

var hash = require('object-hash');

var peter = { name: 'Peter', stapler: false, friends: ['Joanna', 'Michael', 'Samir'] };
var michael = { name: 'Michael', stapler: false, friends: ['Peter', 'Samir'] };
var bob = { name: 'Bob', stapler: true, friends: [] };

/***
 * sha1 hex encoding (default)
 */
hash(peter);
// 14fa461bf4b98155e82adc86532938553b4d33a9
hash(michael);
// 4b2b30e27699979ce46714253bc2213010db039c
hash(bob);
// 38d96106bc8ef3d8bd369b99bb6972702c9826d5

/***
 * hash object keys, values ignored
 */
hash(peter, { excludeValues: true });
// 48f370a772c7496f6c9d2e6d92e920c87dd00a5c
hash(michael, { excludeValues: true });
// 48f370a772c7496f6c9d2e6d92e920c87dd00a5c
hash.keys(bob);
// 48f370a772c7496f6c9d2e6d92e920c87dd00a5c

/***
 * hash object, ignore specific key(s)
 */
hash(peter, { excludeKeys: function(key) {
    if ( key === 'friends') {
      return true;
    }
    return false;
  }
});
// 66b7d7e64871aa9fda1bdc8e88a28df797648d80

/***
 * md5 base64 encoding
 */
hash(peter, { algorithm: 'md5', encoding: 'base64' });
// 6rkWaaDiG3NynWw4svGH7g==
hash(michael, { algorithm: 'md5', encoding: 'base64' });
// djXaWpuWVJeOF8Sb6SFFNg==
hash(bob, { algorithm: 'md5', encoding: 'base64' });
// lFzkw/IJ8/12jZI0rQeS3w==

Legacy Browser Support

IE <= 8 and Opera <= 11 support dropped in version 0.3.0. If you require legacy browser support you must either use an ES5 shim or use version 0.2.5 of this module.

Development

git clone https://github.com/puleos/object-hash

Node Docker Wrapper

If you want to stand this up in a docker container, you should take at look at the node-object-hash project.

gulp tasks

  • gulp watch (default) watch files, test and lint on change/add
  • gulp test unit tests
  • gulp karma browser unit tests
  • gulp lint jshint
  • gulp dist create browser version in /dist

License

MIT

Changelog

v2.0.0

Only Node.js versions >= 6.0.0 are being tested in CI now. No other breaking changes were introduced.