sell product changes

This commit is contained in:
2015-10-05 07:37:17 +02:00
parent e9f9567618
commit 36c8d37914
18 changed files with 704 additions and 141 deletions

View File

@@ -21,9 +21,11 @@ class AppAsset extends AssetBundle
'css/site.css',
];
public $js = [
];
public $depends = [
'yii\web\YiiAsset',
'yii\bootstrap\BootstrapAsset',
'frontend\assets\GrowlAsset'
];
}

View File

@@ -0,0 +1,16 @@
<?php
namespace frontend\assets;
use yii\web\AssetBundle;
class GrowlAsset extends AssetBundle
{
public $sourcePath = '@bower';
public $js = [
'remarkable-bootstrap-notify/bootstrap-notify.min.js'
];
public $depends = [
];
}

View File

@@ -9,8 +9,14 @@ use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use frontend\models\ProductSaleForm;
use frontend\models\ProductLookupForm;
use common\models\Card;
use common\models\Customer;
use yii\base\DynamicModel;
use yii\base\Object;
use common\models\Currency;
use common\models\Account;
use common\models\Discount;
/**
* ProductController implements the CRUD actions for Product model.
@@ -40,11 +46,50 @@ class ProductController extends Controller
$model = new ProductSaleForm();
return $this->render("sale",[
'customer' => $this->customer,
'card' => $this->card
]);
$lookupModel = new ProductLookupForm();
$currencies = Currency::find()->all();
$accounts = Account::readAccounts();
$discounts = Discount::read();
if (Yii::$app->request->isAjax) {
\Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;
$model->currencies = $currencies;
$model->accounts = $accounts;
$model->discounts = $discounts;
$result = [];
$result['code'] = 'unknown';
if ($model->load(Yii::$app->request->post()) ) {
if ( $model->save()){
$result['code'] = 'success';
$result['message'] = Yii::t('common/product',"Sold: {product}" ,[ 'product' => $model->transfer->toProductSoldString() ]);
}else{
$result['code'] = 'invalid';
$result['errors'] = $model->getErrors();
}
}
return $result;
}else{
return $this->render("sale",[
'customer' => $this->customer,
'card' => $this->card,
'model' => $model,
'lookupModel' =>$lookupModel,
'currencies' => $currencies,
'accounts' => $accounts,
'discounts' => $discounts,
]);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace frontend\models;
use Yii;
use yii\base\Model;
use common\models\Card;
use common\models\Customer;
/**
* ContactForm is the model behind the contact form.
*/
class ProductLookupForm extends Model
{
public $filter_text;
/**
* @inheritdoc
*/
public function rules()
{
return [
];
}
/**
* @inheritdoc
*/
public function attributeLabels()
{
return [
'verifyCode' => 'Verification Code',
];
}
}

View File

@@ -6,6 +6,12 @@ use Yii;
use yii\base\Model;
use common\models\Card;
use common\models\Customer;
use common\models\Product;
use common\models\Transfer;
use yii\base\Object;
use common\models\Account;
use common\models\Discount;
use common\models\Currency;
/**
* ContactForm is the model behind the contact form.
@@ -13,25 +19,86 @@ use common\models\Customer;
class ProductSaleForm extends Model
{
public $productNumber;
public $productBarcode;
public $id_product;
public $count;
public $currency;
public $account;
public $id_currency;
public $id_account;
public $id_discount;
public $comment;
public $barcode;
public $product_number;
public $sale_price;
public $product_name;
public $accounts;
public $currencies;
public $discounts;
public $product;
public $account;
public $currency;
public $discount;
public $transfer;
/**
* @inheritdoc
*/
public function rules()
{
return [
[['number'], 'required'],
[['id_product','count','id_account'], 'required'],
[['id_product','id_currency','id_account', 'id_discount','count'], 'integer'],
[['comment'], 'string' ,'max' => 255],
[['id_product' ], 'validateProduct'],
[['count' ], 'validateCount'],
[['id_currency' ], 'validateCurrency'],
[['id_account' ], 'validateAccount'],
[['id_discount' ], 'validateDiscount'],
];
}
public function validateProduct($attribute,$params){
$this->product = Product::findOne($this->id_product);
if ( !isset( $this->product ) ){
$this->addError($attribute, Yii::t('frontend/product', 'Product not found!'));
}
}
public function validateCount($attribute,$params){
if ( $this->product != null ){
if ( $this->product->stock < $this->count ){
$this->addError($attribute, Yii::t('frontend/product', 'Stock {stock} lower then {count}!', [ 'count' => $this->count, 'stock' => $this->product->stock ] ));
}
}
}
public function validateCurrency($attribute,$params){
if ( isset($this->id_currency ) ){
$this->currency = Currency::findOne($this->id_currency);
if ( !isset( $this->currency ) ){
$this->addError($attribute,Yii::t('frontend/product', 'Currency not found') );
}
}
}
public function validateAccount($attribute,$params){
$this->account = Account::findOne($this->id_account);
}
public function validateDiscount($attribute,$params){
if ( isset( $this->id_discount ) ){
$this->discount = Discount::findOne($this->id_discount);
if ( !isset( $this->discount ) ){
$this->addError($attribute,Yii::t('frontend/product', 'Discount not found') );
}
}
}
/**
* @inheritdoc
*/
@@ -42,5 +109,32 @@ class ProductSaleForm extends Model
];
}
public function save(){
if ( $this->validate() ){
$this->saveTransfer();
$this->saveProduct();
return true;
}
return false;
}
protected function saveTransfer(){
$this->transfer = Transfer::createProductTransfer($this->account, $this->discount, $this->currency, $this->count, $this->product);
/*
*/
$this->transfer->status = Transfer::STATUS_PAID;
if ( isset($this->comment)){
$this->transfer->comment = $this->comment;
}
$this->transfer->id_user = Yii::$app->user->id;
$this->transfer->save();
}
protected function saveProduct(){
Product::sellProduct($this->product, $this->count);
$this->product->save();
}
}

View File

@@ -1,85 +1,106 @@
<?php
use yii\helpers\Html;
use yii\bootstrap\ActiveForm;
use yii\helpers\ArrayHelper;
/* @var $this yii\web\View */
/* @var $model frontend\models\ProductSaleForm */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $currencies common\models\Currency[] */
function mkOptions($options){
// $o = $options;
$all = ['' => '-' ];
$o = $all + $options;
return $o;
}
$currencyOptions = mkOptions( ArrayHelper::map($currencies, 'id_currency', 'name') );
$accountOptions = mkOptions( ArrayHelper::map($accounts, 'id_account', 'name') );
$discountOptions = mkOptions( ArrayHelper::map($discounts, 'id_discount', 'name') );
?>
<?php ?>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Product name'))?>
</div>
<div class='col-md-6'>
<?php echo Html::tag('span','',[ 'class' => 'product product-name']); ?>
<div class="col-md-12">
<?php echo $this->render('_view')?>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Product price'))?>
</div>
<div class='col-md-6'>
<?php echo Html::tag('span','',[ 'class' => 'product product-price']); ?>
<?php $form = ActiveForm::begin([
'id' => 'filter_text_form',
'class' =>'form-inline',
'layout' => 'horizontal',
'fieldConfig' => [
'horizontalCssClasses' => [
'label' => 'col-sm-5',
'offset' => 'col-sm-offset-6',
'wrapper' => 'col-sm-7',
'error' => '',
'hint' => '',
],
],
] )?>
<div class='col-md-12'>
<?php echo $form->field($lookupModel,'filter_text')->textInput(['id'=>'filter_text']); ?>
</div>
<?php ActiveForm::end()?>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Product number'))?>
<?php $form = ActiveForm::begin(
[
'id' => 'product_form',
'class' =>'form-inline',
'layout' => 'horizontal',
'fieldConfig' => [
'horizontalCssClasses' => [
'label' => 'col-sm-5',
'offset' => 'col-sm-offset-6',
'wrapper' => 'col-sm-7',
'error' => '',
'hint' => '',
],
],
]
); ?>
<?php echo Html::activeHiddenInput($model, 'id_product') ?>
<div class="row">
<div class='col-md-12'>
<?php echo $form->field($model, 'count')->input("number") ?>
</div>
</div>
<div class='col-md-6'>
<?php echo Html::tag('span','',[ 'class' => 'product product-number']); ?>
<div class="row">
<div class='col-md-12'>
<?php echo $form->field($model,'id_currency')->dropDownList($currencyOptions) ?>
</div>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Barcode'))?>
<div class="row">
<div class='col-md-12'>
<?php echo $form->field($model,'id_account')->dropDownList($accountOptions) ?>
</div>
</div>
<div class='col-md-6'>
<?php echo Html::tag('span','',[ 'class' => 'product barcode']); ?>
<div class="row">
<div class='col-md-12'>
<?php echo $form->field($model,'id_discount')->dropDownList($discountOptions) ?>
</div>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Count'))?>
<div class="row">
<div class='col-md-12'>
<?php echo $form->field( $model,'comment' )->textarea() ?>
</div>
</div>
<div class='col-md-6'>
<?php echo Html::textInput('count') ?>
<div class="row">
<div class='col-md-5'>
<?php echo Html::a(Yii::t("frontend/product","Sell product"),null,['class' => 'btn btn-success', 'id' => 'btn_sell'] );?>
</div>
<div class='col-md-7'>
<?php echo Html::a(Yii::t("frontend/product","Sell product and add to total"),null,['class' => 'btn btn-success', 'id' => 'btn_sell_append'] );?>
</div>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Currency'))?>
</div>
<div class='col-md-6'>
<?php echo Html::dropDownList('currency',null,[],[]); ?>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Account'))?>
</div>
<div class='col-md-6'>
<?php echo Html::dropDownList('account',null,[],[]); ?>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Discount'))?>
</div>
<div class='col-md-6'>
<?php echo Html::dropDownList('discount',null,[],[]); ?>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Comment'))?>
</div>
</div>
<div class="row">
<div class='col-md-10'>
<?php echo Html::textarea('comment', ''); ?>
</div>
</div>
<div class="row">
<div class='col-md-3'>
<?php echo Html::a(Yii::t("frontend/product","Sell product"),null,['class' => 'btn btn-success'] );?>
</div>
<div class='col-md-7'>
<?php echo Html::a(Yii::t("frontend/product","Sell product and add to total"),null,['class' => 'btn btn-success'] );?>
</div>
</div>
<?php ActiveForm::end(); ?>

View File

@@ -1,19 +1,9 @@
<?php
use yii\bootstrap\Html;
?>
<div class="row">
<div class='col-md-10'>
<?php echo Html::label(Yii::t('frontend/product', 'Bill'))?>
</div>
</div>
<div class="row">
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Debit'))?>
</div>
<div class='col-md-6'>
<?php echo Html::tag("span",'0,00',['sale', 'sale-debit'])?>
</div>
</div>
<div class="row">
<div class='col-md-12'>
<table class="table table-bordered table-striped">
@@ -37,27 +27,6 @@ use yii\bootstrap\Html;
</tr>
</thead>
<tbody>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
</tbody>
</table>
</div>

View File

@@ -0,0 +1,56 @@
<?php
?>
<table class="table table-bordered table-striped">
<tbody>
<tr>
<th>
<?php echo Yii::t('frontend/product','Name')?>
</th>
<td colspan="3">
<span class="product-name"></span>
</td>
</tr>
<tr>
<th>
<?php echo Yii::t('frontend/product','Barcode')?>
</th>
<td>
<span class="product-barcode">123456789</span>
</td>
<th>
<?php echo Yii::t('frontend/product','Product number')?>
</th>
<td>
<span class="product-number">123456789</span>
</td>
</tr>
<tr>
<th>
<?php echo Yii::t('frontend/product','Stock'). ' (Db)'?>
</th>
<td>
<span class="product-stock"></span>
</td>
<th>
<?php echo Yii::t('frontend/product','Count'). ' (Db)'?>
</th>
<td>
<span class="product-count">1</span>
</td>
</tr>
<tr>
<th>
<?php echo Yii::t('frontend/product','Sale Price')?>
</th>
<td>
<span class="product-sale-price"></span>
</td>
<th>
<?php echo Yii::t('frontend/product','Price')?>
</th>
<td>
<span class="product-price">100 000</span>
</td>
</tr>
</tbody>
</table>

View File

@@ -6,6 +6,12 @@ use yii\helpers\Html;
use common\models\Product;
use frontend\assets\ProductSellAsset;
use yii\helpers\Url;
use yii\bootstrap\ActiveForm;
use yii\helpers\ArrayHelper;
/* @var $this yii\web\View */
/* @var $form yii\bootstrap\ActiveForm */
/* @var $currencies common\models\Currency[] */
ProductSellAsset::register($this);
@@ -20,9 +26,19 @@ $this->registerJs ( 'new ProductSell( '. json_encode($options).');' );
?>
<style>
/*
.product-form input, .product-form select, .product-form textarea{
width: 100%;
}
*/
.product-count{
text-align: right;
}
.form-group{
margin-bottom: 3px;
}
</style>
<div class='row'>
@@ -32,23 +48,11 @@ $this->registerJs ( 'new ProductSell( '. json_encode($options).');' );
<div class='col-md-4'>
<?php echo ReceptionCardNumberWidget::widget( [ 'customer' => $customer, 'card' =>$card, 'route' => ['product/sale'] ] )?>
</div>
<div class='col-md-4'>
</div>
</div>
<h1><?php echo Yii::t('frontend/product','Sell product')?></h1>
<div class='row'>
<div class='col-md-4'>
<?php echo Html::label(Yii::t('frontend/product', 'Product'))?>
<?php echo Html::textInput('filter_text','', ['id'=>'filter_text'])?>
</div>
<div class='col-md-4'>
</div>
<div class='col-md-4'>
</div>
</div>
<div class='row '>
<div class='col-md-6 product-form'>
<?php echo $this->render('_sale_form' ) ?>
<?php echo $this->render('_sale_form' ,['model' =>$model , 'lookupModel' =>$lookupModel, 'currencies' => $currencies, 'accounts' => $accounts,'discounts' => $discounts,]) ?>
</div>
<div class='col-md-6'>
<?php echo $this->render('_sold_items' ) ?>

View File

@@ -1,35 +1,98 @@
function ProductSell(o){
var app = this;
var product = null;
this.defaults = {
selector_filter_text: '#filter_text',
lookup_product_url: ''
lookup_product_url: '' ,
selector_form: '#product_form',
form_invalid: 'Az ürlap hibákat tartalmaz'
};
init();
function init(){
this.defaults = $.extend(this.defaults, o );
$.extend(app.defaults, o );
addBehaviorEnterPressedListener();
addBehaviourBtnSell();
addBehaviourBtnSellAndAppendToBill();
addBehaviorAjaxSubmit();
setFocus();
addBehaviorCountEnterPressedListener();
addBehaviorCountChangedListener();
addBehaviorCurrencyEnterPressedListener();
addBehaviorAccountEnterPressedListener();
addBehaviorDiscountEnterPressedListener();
productChanged();
}
function setFocus(){
$("#filter_text").focus();
}
function addBehaviorEnterPressedListener(){
alert($( this.defaults.selector_filter_text ).length);
$( this.defaults.selector_filter_text ).keypress(function( event ) {
$( app.defaults.selector_filter_text ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
lookupProduct();
}
});
}
function addBehaviorCountEnterPressedListener(){
$( '#productsaleform-count' ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
event.stopImmediatePropagation();
$('#productsaleform-id_currency').focus();
}
});
}
function addBehaviorCurrencyEnterPressedListener(){
$( '#productsaleform-id_currency' ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
event.stopImmediatePropagation();
$('#productsaleform-id_account').focus();
}
});
}
function addBehaviorAccountEnterPressedListener(){
$( '#productsaleform-id_account' ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
event.stopImmediatePropagation();
$('#productsaleform-id_discount').focus();
}
});
}
function addBehaviorDiscountEnterPressedListener(){
$( '#productsaleform-id_discount' ).keypress(function( event ) {
if ( event.which == 13 ) {
event.preventDefault();
event.stopImmediatePropagation();
$('#productsaleform-comment').focus();
}
});
}
function addBehaviorCountChangedListener(){
$( '#productsaleform-count' ).change(function( event ) {
refreshCalculatedValues();
});
}
function lookupProduct(){
var data, url;
url = this.defaults.lookup_product_url;
url = app.defaults.lookup_product_url;
data = {
'query' : $( this.defaults.selector_filter_text ).val()
'query' : $( app.defaults.selector_filter_text ).val()
};
$.ajax({
@@ -41,27 +104,106 @@ function ProductSell(o){
}
function onLookupProductReady( data ){
alert('ok');
productChanged(data.product);
app.product = data.product;
productChanged();
}
function productChanged(product){
function productChanged( ){
clearForm();
if ( product == null){
applyProduct();
if ( app.product != null){
applyProduct( app.product);
refreshCalculatedValues();
$("#productsaleform-count").focus().select();
}
}
function clearForm(){
$('.product-name').html('-');
$('.product-price').html('-');
$('.product-number').html('-');
$('.product-barcode').html('-');
$('.product-stock').html('-');
$('.product-price').html('-');
$('.product-sale-price').html('-');
$("#productsaleform-count").val(1);
$('#productsaleform-id_product').val('');
$('#productsaleform-id_account').val('');
}
function applyProduct(product){
$('#productsaleform-id_product').val(product.id_product);
$('.product-name').html(product.name);
$('.product-sale-price').html(product.sale_price);
$('.product-number').html(product.product_number);
$('.product-barcode').html(product.barcode);
$('.product-stock').html(product.stock);
$('#productsaleform-id_account').val(product.id_account);
}
function refreshCalculatedValues(){
var count,price;
count = $("#productsaleform-count").val();
count = +count;
if ( isNaN(count)){
count = 0;
}
price = count * app.product.sale_price;
$('.product-count').html(count);
$('.product-price').html(price);
}
function addBehaviourBtnSell(){
$('#btn_sell').on('click',submitSell);
}
function addBehaviourBtnSellAndAppendToBill(){
$('#btn_sell_append').on('click',submitSell);
}
function submitSell(){
$('#product_form').submit();
}
function addBehaviorAjaxSubmit(){
$('body').on('beforeSubmit', '#product_form', function () {
var form = $(this);
// return false if form still have some validation errors
if (form.find('.has-error').length) {
$.notify(app.defaults.form_invalid, { 'type' : 'success' });
return false;
}
// submit form
$.ajax({
url: form.attr('action'),
type: 'post',
data: form.serialize(),
success: function (response) {
// do something with response
if ( response.code == 'success'){
$.notify(response.message, { 'type' : 'success' });
clearForm();
refreshCalculatedValues();
$("#filter_text").val('');
setFocus();
}else if ( response.code == 'invalid'){
if ( response.errors ){
$.each(response.errors, function (key, value){
var message;
message = $.map(value, function(obj){ return obj }).join(' ');
$.notify(message, { 'type' : 'danger' });
}
);
}
}
}
});
return false;
});
}
}