Commit 88de0202 by Damien Moulard

sales export

parent d2cb5b42
dev_cooperatic #5673_bug_calendrier_echange_service 3832-makeups-and-member-status-update 4081 4444_improve_presence_recording 4709 4778-reception-dont-get-finished-orders 4809-remove-shelf-value-col-to-reduce-server-load 4880-rapports-reception-faux 4950-douchage-appli-reception 5474-et-5462-Voir-les-rattrapages-choisis-dans-admin-bdm-et-corrige-lenteur-affichage-admin-rattrapages 5641-reception-trier-a-la-maj-prix-dans-ordre-de-pointage-quantites 6286_bug_encaissement_souscription_cheque_espece 6813-marking-parent-gone-when-unpairing-binom-does-not-unsuscribe-parent-from-shift-template 6832--certaines-absences-engendrent-une-erreur 7723-7559-change-purchase-order-workflow-django-side 7731-third-party-side-brinks-pos-export-not-working 7747-inventaire-par-article 7800-make-test-solution-work 7819-prevent-adding-product-already-in-order 7848-cannot-validate-qty-with-decimal-on-kg-product 7918_bug_quantites_stade_demande_prix adaptation_supercafoutch adaptation_supercoop adaptation_supercoop_supercafoutch adpatation_chouette assistance_import_article coop_dev_necessitant_modules_bdm_odoo_modifies correctif_nb_rattrapages_creation_binome_avec_ajout_automatique_au_point_negatif dev_lgds dev_principale dev_principale_clean docker export_capital_detenu fix_bug_process_picking fusion_custom_graoucoop graoucoop_backup graoucoop_prod graoucoop_tmp hot_fix_shelf_labels_auto_print howto impression_etiquettes_rayons integration_lien_precommandes_dans_espace_membre lacagette_prod local_branch master meal-voucher-and-label-printer-software-bug migration-v12 pour_graoucoop_prod pour_version_prod_cagette refonte_espace_membre_sc retouches_tickets_supercoop sc-setup-stock-app supercafoutch-preprod supercafoutch-prod-20221003 supercafoutch_prod ticket_4146 20210701 20210603 supercafoutch_20250120_151258 supercafoutch_20250120_150340 supercafoutch_20240909_080630 supercafoutch_20240609_115709 supercafoutch_20240212_082431 supercafoutch_20240107_181851 supercafoutch_prod_until_240107 supercafoutch-prod-20221003 supercafoutch-230911 supercafoutch-230824 supercafoutch-230823 supercafoutch-230823-the-true-one migration-v12-tag lacagette_20240310_074751 lacagette_20240107_122554 lacagette_20240107_120916 graoucoop_20240609_122614 cagette_testtag cagette-230814 cagette-230630
2 merge requests!24Cooperatic and LGDS improvements,!11Intégrations dev Coopératic 2 dernières semaines avril
......@@ -52,6 +52,7 @@ INSTALLED_APPS = (
'orders',
'shop',
'shelfs',
'sales',
# 'tests'
)
......
......@@ -44,6 +44,7 @@ urlpatterns = [
url(r'^website/', include('website.urls')),
url(r'^shop/', include('shop.urls')),
url(r'^shelfs/', include('shelfs.urls')),
url(r'^sales/', include('sales.urls')),
]
try:
......
from django.contrib import admin
# Register your models here.
from django.apps import AppConfig
class SalesConfig(AppConfig):
name = 'sales'
from django.db import models
from outils.common_imports import *
from outils.common import OdooAPI
class CagetteSales(models.Model):
"""Class to manage operations on envelops"""
def __init__(self):
"""Init with odoo id."""
self.o_api = OdooAPI()
def get_sales(self, date_from, date_to):
res = []
# Get pos sessions
cond = [['stop_at', '>=', date_from], ['stop_at', '<=', date_to], ['state', '=', "closed"]]
fields = []
sessions = self.o_api.search_read('pos.session', cond, fields)
# Get bank statements of these sessions
statements = []
for s in sessions:
statements = statements + s["statement_ids"]
# Get payment lines
cond = [['statement_id', 'in', statements]]
fields = ["partner_id", "amount", "journal_id", "create_date", "date"]
payments = self.o_api.search_read('account.bank.statement.line', cond, fields, order="create_date ASC")
item = None
try:
for payment in payments:
if item is not None and item["partner_id"][0] == payment["partner_id"][0] and item["date"] == payment["date"]:
res[len(res)-1]["total_amount"] += round(float(payment["amount"]), 2)
res[len(res)-1]["payments"].append({
"amount": round(float(payment["amount"]), 2),
"journal_id": payment["journal_id"]
})
else:
item = {
"partner_id": payment["partner_id"],
"create_date": payment["create_date"],
"date": payment["date"],
"total_amount": round(float(payment["amount"]), 2),
"payments": [
{
"amount": round(float(payment["amount"]), 2),
"journal_id": payment["journal_id"]
}
]
}
res.append(item)
except Exception as e:
pass
return res
.select_sales_dates {
margin-top: 25px;
}
.sales_date {
display: inline-block;
margin-right: 10px;
}
.main {
margin-top: 25px;
}
.table_area {
margin: auto;
width: 90%;
padding: 10px;
}
.select_sales_date_input {
border-radius:5px;
}
\ No newline at end of file
var dateFormat = "yy-mm-dd",
from_datepicker = null,
to_datepicker = null,
orders_table = null;
// Return a date from a string if valid, else return null
function getDate(element) {
var date = null;
try {
date = $.datepicker.parseDate(dateFormat, element);
} catch (error) {
date = null;
}
return date;
}
// Enable validation button if all fields are valid
function enable_validation() {
if (getDate(from_datepicker.val()) &&
getDate(to_datepicker.val())) {
$('#dates_selection_button').prop('disabled', false);
} else {
$('#dates_selection_button').prop('disabled', true);
}
}
function display_orders(orders) {
// Empty datatable if already exists
if (orders_table) {
orders_table.destroy();
}
console.log(orders);
orders_table = $('#orders_table').DataTable({
data: orders,
columns:[
{
data:"create_date",
title:"Date",
width: "10%"
},
{
data:"partner_id",
title:"Membre",
width: "50%",
render: function (data) {
return data[1];
}
},
{
data:"total_amount",
title: "Montant du panier",
className:"dt-body-center",
render: function (data) {
return parseFloat(data).toFixed(2) + ' €';
}
},
{
data:"payments",
title:"Paiements",
className:"dt-body-center",
orderable: false,
render: function (data) {
let res = '<ul>';
for (p of data) {
res += `<li>${p.journal_id[1]} : ${p.amount} €</li>`
}
res += "</ul>"
return res;
}
}
],
order: [
[
0,
"asc"
]
],
dom: 'rtip',
iDisplayLength: 25,
language: {url : '/static/js/datatables/french.json'}
});
$('.main').show();
}
function get_sales() {
openModal();
var url = "/sales/get_sales";
url += '?from=' + encodeURIComponent(from_datepicker.val());
url += '&to=' + encodeURIComponent(to_datepicker.val());
$.ajax({
type: 'GET',
url: url,
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
display_orders(data.res);
closeModal();
},
error: function(data) {
err = {msg: "erreur serveur lors de la sélection des mouvements de stock", ctx: 'get_movements'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'stock');
closeModal();
alert('Erreur lors de la récupération, réessayez plus tard');
}
});
}
$(document).ready(function() {
$.ajaxSetup({ headers: { "X-CSRFToken": getCookie('csrftoken') } });
// Set datepicker
$.datepicker.regional['fr'] = {
monthNames: [
'Janvier',
'Fevrier',
'Mars',
'Avril',
'Mai',
'Juin',
'Juillet',
'Aout',
'Septembre',
'Octobre',
'Novembre',
'Decembre'
],
dayNamesMin: [
'Di',
'Lu',
'Ma',
'Me',
'Je',
'Ve',
'Sa'
],
dateFormat: dateFormat,
firstDay: 1,
minDate: 1,
maxDate: '+12M +0D'
};
$.datepicker.setDefaults($.datepicker.regional['fr']);
from_datepicker = $("#from")
.datepicker({
defaultDate: "-1d",
changeMonth: true,
changeYear: true,
yearRange: "-03:+00",
minDate: new Date(2007, 1 - 1, 1),
maxDate: new Date()
})
.on("change", function() {
to_datepicker.datepicker("option", "minDate", getDate(this.value));
});
to_datepicker = $("#to")
.datepicker({
defaultDate: "-1d",
changeMonth: true,
changeYear: true,
yearRange: "-03:+00",
minDate: new Date(2007, 1 - 1, 1),
maxDate: new Date()
})
.on("change", function() {
from_datepicker.datepicker("option", "maxDate", getDate(this.value));
});
$('.select_sales_date_input').change(function() {
enable_validation();
});
$( "#sales_form" ).submit(function( event ) {
event.preventDefault();
get_sales();
});
// $('#dates_selection_button').click(function() {
// get_sales();
// });
});
"""."""
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.index),
url(r'^get_sales$', views.get_sales),
]
from outils.common_imports import *
from outils.for_view_imports import *
from sales.models import CagetteSales
def index(request):
"""Display sales export screen"""
context = {'title': 'Export de ventes'}
template = loader.get_template('sales/index.html')
# m = CagetteSales()
# sales = m.get_sales()
# print(sales)
return HttpResponse(template.render(context, request))
def get_sales(request):
res = {}
date_from = request.GET.get('from', '')
date_to = request.GET.get('to', '')
m = CagetteSales()
res = m.get_sales(date_from, date_to)
if 'errors' in res and res['errors']:
return JsonResponse(res, status=500)
else:
return JsonResponse({'res': res})
\ No newline at end of file
{% extends "base.html" %}
{% load static %}
{% block additionnal_css %}
<link rel="stylesheet" href="{% static 'css/datatables/jquery.dataTables.css' %}">
<link rel="stylesheet" href="{% static 'jquery-ui-1.12.1/jquery-ui.min.css' %}">
<link rel="stylesheet" href="{% static "css/sales.css" %}?v=">
{% endblock %}
{% block additionnal_scripts %}
<script type="text/javascript" src="{% static 'jquery-ui-1.12.1/jquery-ui.min.js' %}?v="></script>
<script type="text/javascript" src="{% static 'js/datatables/jquery.dataTables.min.js' %}"></script>
<script type="text/javascript" src="{% static 'js/datatables/dataTables.plugins.js' %}"></script>
{% endblock %}
{% block content %}
<div class="page_body">
<div id="content_main" class="page_content">
<div class="header txtcenter">
<h1>Extraction de ventes</h1>
</div>
<div class="select_sales_dates txtcenter">
<form id="sales_form" action="javascript:;">
<div class="sales_date">
<label for="from">Entre :</label>
<input type="text" name="from" id="from" class="select_sales_date_input" required>
</div>
<div class="sales_date">
<label for="to">et :</label>
<input type="text" name="to" id="to" class="select_sales_date_input" required>
</div>
<button type="submit" class="btn--primary" id="dates_selection_button" disabled>C'est parti !</button>
</form>
</div>
<div class="main" style="display:none;">
<div class="table_area">
<table id="orders_table" class="display" cellspacing="0" width="100%"></table>
</div>
</div>
</div>
<div id="templates" style="display:none;">
</div>
</div>
<script src="{% static "js/all_common.js" %}?v="></script>
<script src="{% static "js/sales.js" %}?v="></script>
{% endblock %}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment